Swift中与Objective-C中的isEqualToString相对应的是什么?

291

我正在尝试运行以下代码:

import UIKit

class LoginViewController: UIViewController {

@IBOutlet var username : UITextField = UITextField()
@IBOutlet var password : UITextField = UITextField()

@IBAction func loginButton(sender : AnyObject) {

    if username .isEqual("") || password.isEqual(""))
    {
        println("Sign in failed. Empty character")
    }
}

我的之前的代码是用Objective-C编写的,它一直运行良好:

 if([[self.username text] isEqualToString: @""] ||
    [[self.password text] isEqualToString: @""] ) {

我认为在Swift中不能使用isEqualToString

8个回答

460

使用 Swift,您不再需要使用 isEqualToString 进行相等性检查。

现在可以使用 ==

示例:

let x = "hello"
let y = "hello"
let isEqual = (x == y)

现在isEqual的值为true


42
=== 是身份运算符,而 == 则是相等运算符(默认情况下在 NSObject 及其子类上调用 isEqual: 方法)。 - Bryan Chen
3
是的,抱歉,“平等”而不是“身份相同”。错词了 :) - JJSaccolo
1
但是,除非我漏掉了什么,否则似乎无法测试字符串之间的身份“String”不符合协议“AnyObject”。 - user1040049
3
在Swift中,String是一个结构体而不是类,所以你不能使用===操作符进行字符串比较。如果你将文本/字符串强制转换为NSString类型,就可以使用===操作符进行比较。请注意,这样做并不会改变原始字符串的类型或值,只是让你能够使用===操作符进行比较。 - sanjana
3
@JJSaccolo在身份验证方面误导了你。这个问题是关于String比较的。Xcode 6.4会返回错误Binary operator '===' cannot be applied to two String operands - Dima Deplov
显示剩余2条评论

52

请使用 == 运算符代替 isEqual

比较字符串

Swift 提供三种比较字符串的方法:字符串相等、前缀相等和后缀相等。

字符串相等

如果两个字符串包含的字符完全相同且顺序一致,则它们被认为是相等的:

let quotation = "We're a lot alike, you and I."
let sameQuotation = "We're a lot alike, you and I."
if quotation == sameQuotation {
    println("These two strings are considered equal")
}
// prints "These two strings are considered equal"
.
.
.

欲了解更多,请参阅Swift官方文档(搜索字符串比较)


13

除了 @JJSaccolo 的答案之外,你还可以创建自定义的 equals 方法作为新的字符串扩展,例如:

extension String {
     func isEqualToString(find: String) -> Bool {
        return String(format: self) == find
    }
}

并使用:

let a = "abc"
let b = "abc"

if a.isEqualToString(b) {
     println("Equals")
}

当然,原始运算符 == 可能更好(像在Javascript中那样工作),但对我来说, isEqual 方法使代码更清晰,以便我们比较字符串。

希望这能对某些人有所帮助,


不确定在存在Comparable协议的情况下是否应该这样做。https://developer.apple.com/documentation/swift/comparable - Zaporozhchenko Oleksandr

9

在Swift中,==操作符等同于Objective C的isEqual:方法(它调用isEqual方法而不仅仅是比较指针,还有一个新的===方法用于测试指针是否相同),因此您可以将其编写为:

if username == "" || password == ""
{
    println("Sign in failed. Empty character")
}

虽然这在Swift中可以工作,但如果/当用户名为nil时,它将在Objective-C中造成混乱。如上所建议 - 使用username.isEmpty,并且在某个地方有一个等效的isEmpty宏可用于Objective-C。 - johndpope
在 Swift 中,除非将用户名声明为 String?(也称为 Optional<String>),否则它不能为 nil。在 Objective-C 中,您只需说 if ([username length] == 0 || [password length] == 0) { ... } 来处理 nil 或空的情况。 - Nick Lockwood

6
实际上,Swift似乎试图将字符串的处理方式从对象转变为值。但是这并不意味着在后台,Swift不将字符串作为对象处理。你们肯定会注意到,您仍然可以调用字符串的方法和使用它们的属性。
例如:
//example of calling method (String to Int conversion)
let intValue = ("12".toInt())
println("This is a intValue now \(intValue)")


//example of using properties (fetching uppercase value of string)
let caUpperValue = "ca".uppercaseString
println("This is the uppercase of ca \(caUpperValue)")

在Objective-C中,您可以通过变量传递对字符串对象的引用,并调用其方法,这基本上说明了字符串是纯对象。
然而,在Swift中,当您尝试将字符串视为对象时,无法通过变量按引用传递字符串对象。Swift始终会传递全新的字符串副本。因此,在Swift中,字符串更常被称为值类型。实际上,两个字符串常量将不相同(===),它们被视为两个不同的副本。
let curious = ("ca" === "ca")
println("This will be false.. and the answer is..\(curious)")

正如您所看到的,我们开始摆脱将字符串视为对象的传统思维方式,更多地将其视为值。因此,在Swift中,被视为字符串对象的身份运算符的.isEqualToString不再有效,因为您永远无法获取两个相同的字符串对象。您只能比较它的值,换句话说就是检查相等性(==)。

 let NotSoCuriousAnyMore = ("ca" == "ca")
 println("This will be true.. and the answer is..\(NotSoCuriousAnyMore)")

当你看到Swift中字符串对象的可变性时,这会变得更加有趣。但这是另一个问题,另一天的事情了。你应该去了解一下,因为它真的很有趣。 :) 希望这能消除一些困惑。干杯!


4

以下是我使用的UITextField文本比较代码,对我来说很有效,如果您发现任何错误,请让我知道。

if(txtUsername.text.isEmpty || txtPassword.text.isEmpty)
{
    //Do some stuff
}
else if(txtUsername.text == "****" && txtPassword.text == "****")
{
    //Do some stuff
}

3
在Swift中,isEmpty函数用于检查字符串是否为空。
 if username.isEmpty || password.isEmpty {
      println("Sign in failed. Empty character")
 }

3

一个重要的点是,Swift中字符串的==可能与Objective-C中的-isEqualToString:不等价。其特殊之处在于Swift和Objective-C之间字符串表示方式的差异。

看一个例子:

let composed = "Ö" // U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
let decomposed = composed.decomposedStringWithCanonicalMapping // (U+004F LATIN CAPITAL LETTER O) + (U+0308 COMBINING DIAERESIS)

composed.utf16.count // 1
decomposed.utf16.count // 2

let composedNSString = composed as NSString
let decomposedNSString = decomposed as NSString

decomposed == composed // true, Strings are equal
decomposedNSString == composedNSString // false, NSStrings are not

NSString是由一系列UTF-16代码单元表示的(可大致理解为UTF-16(定宽)代码单元数组)。而Swift的String概念上是“字符”的序列,其中“字符”是抽象的扩展字形集群(读作Character = 任意数量的Unicode代码点,通常是用户看到的字符和文本输入光标跳转的位置)。

接下来要提到的是Unicode。对于它有很多要写的,但在这里我们感兴趣的是所谓的“规范等价”。使用Unicode代码点,视觉上相同的“字符”可以以多种方式进行编码。例如,“Á”可以被表示为一个预先组合的“Á”,也可以是一个分解的A + ◌́(这就是为什么示例中composed.utf16decomposed.utf16具有不同长度的原因)。阅读关于这个内容的好文章,可以查看这篇精彩的文章

-[NSString isEqualToString:],根据文档,逐个比较NSString的代码单元,所以:

[Á] != [A, ◌́]

Swift的String ==会通过规范等价比较字符。

[ [Á] ] == [ [A, ◌́] ]

在Swift中,上述示例将对字符串返回true。这就是为什么`-[NSString isEqualToString:]`不等同于Swift的String ==。可以通过比较字符串的UTF-16视图来进行等效的纯Swift比较:
decomposed.utf16.elementsEqual(composed.utf16) // false, UTF-16 code units are not the same
decomposedNSString == composedNSString // false, UTF-16 code units are not the same
decomposedNSString.isEqual(to: composedNSString as String) // false, UTF-16 code units are not the same

此外,在Swift中NSString == NSStringString == String之间存在差异。 NSString ==将导致使用isEqual和UTF-16代码单元逐个比较,而String ==将使用规范等价性:

decomposed == composed // true, Strings are equal
decomposed as NSString == composed as NSString // false, UTF-16 code units are not the same

整个示例代码如下:

let composed = "Ö" // U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
let decomposed = composed.decomposedStringWithCanonicalMapping // (U+004F LATIN CAPITAL LETTER O) + (U+0308 COMBINING DIAERESIS)

composed.utf16.count // 1
decomposed.utf16.count // 2

let composedNSString = composed as NSString
let decomposedNSString = decomposed as NSString

decomposed == composed // true, Strings are equal
decomposedNSString == composedNSString // false, NSStrings are not

decomposed.utf16.elementsEqual(composed.utf16) // false, UTF-16 code units are not the same
decomposedNSString == composedNSString // false, UTF-16 code units are not the same
decomposedNSString.isEqual(to: composedNSString as String) // false, UTF-16 code units are not the same

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接