【问题标题】:What is the Swift equivalent of isEqualToString in Objective-C?Objective-C 中 isEqualToString 的 Swift 等价物是什么?
【发布时间】:2014-07-28 14:26:59
【问题描述】:

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

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。任何帮助将不胜感激。

【问题讨论】:

    标签: string swift


    【解决方案1】:

    使用 Swift,您不再需要检查与 isEqualToString 的相等性

    您现在可以使用==

    例子:

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

    现在 isEqual 是 true

    【讨论】:

    • === 是身份运算符,而 == 是相等运算符(默认情况下,在 NSObject 及其子类上调用 isEqual:
    • 是的,对不起,“平等”,而不是身份。错误的词:)
    • 但是,除非我遗漏了什么,否则您似乎无法测试字符串之间的 identity'String' does not conform to protocol 'AnyObject'
    • @user1040049 您不能使用 === 运算符比较字符串,因为 swift 中的字符串是结构类型而不是类。如果您将文本/字符串类型转换为 NSString,则可以使用 === 运算符进行比较。
    • @JJSaccolo 你真的误导了身份部分。这个关于String比较的问题。 Xcode 6.4 返回错误Binary operator '===' cannot be applied to two String operands
    【解决方案2】:

    使用 == 运算符而不是 isEqual

    比较字符串

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

    字符串相等

    如果两个字符串值以相同的顺序包含完全相同的字符,则认为它们相等:

    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"
    .
    .
    .
    

    更多信息请阅读official documentation of Swift (search Comparing Strings).

    【讨论】:

      【解决方案3】:

      除了@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 方法提供了一些我们比较字符串的代码清晰度

      希望对某人有所帮助,

      【讨论】:

      【解决方案4】:

      在 Swift 中,== 运算符等价于 Objective C 的 isEqual: 方法(它调用 isEqual 方法而不只是比较指针,并且有一个新的 === 方法来测试指针是否相同),所以你可以这样写:

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

      【讨论】:

      • 虽然这在 swift 中有效 - 如果 / 当用户名为零时,它将在 objc 中造成严重破坏。如上所述 - 使用 username.isEmpty 并且在某处为目标 c 提供了一个等效的 isEmpty 宏。
      • 在 Swift 中,除非用户名被声明为字符串? (aka Optional) 那么它不能为零。在 Objective C 中,你可以只说 if ([username length] == 0 || [password length] == 0) { ... } 来覆盖 nil 或空的情况。
      【解决方案5】:

      实际上,感觉就像 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)")
      

      在 objectC 中,您可以通过变量传递对字符串对象的引用,并在其上调用方法,这几乎确立了字符串是纯对象的事实。

      当您尝试将 String 视为对象时,这是一个问题,在 swift 中,您不能通过变量通过引用传递字符串对象。 Swift 总是会传递一个全新的字符串副本。因此,字符串在 swift 中通常被称为值类型。事实上,两个字符串文字不会相同(===)。它们被视为两个不同的副本。

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

      如您所见,我们开始摆脱将字符串视为对象的传统方式,并将它们更多地视为值。因此,被视为字符串对象的标识运算符的 .isEqualToString 不再有效,因为您永远无法在 Swift 中获得两个相同的字符串对象。您只能比较它的值,或者换句话说,检查是否相等(==)。

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

      当您在 swift 中查看字符串对象的可变性时,这会变得更有趣。但那是另一个问题,另一天。你可能应该研究的东西,因为它真的很有趣。 :) 希望能消除一些困惑。干杯!

      【讨论】:

        【解决方案6】:

        对于 UITextField 文本比较,我使用下面的代码并且工作正常,如果您发现任何错误,请告诉我。

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

        【讨论】:

          【解决方案7】:

          在 Swift 中,isEmpty 函数会检查字符串是否为空。

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

          【讨论】:

            【解决方案8】:

            重要的一点是 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's 表示为 UTF-16 代码单元序列(大致读取为 UTF-16(固定宽度)代码单元数组)。而 Swift Strings 在概念上是“字符”序列,其中“字符”是抽象扩展字素簇的东西(读取字符 = 任意数量的 Unicode 代码点,通常用户视为字符和文本输入光标跳转的东西周围)。

            接下来要提到的是 Unicode。关于它有很多要写的,但这里我们对一种叫做“规范等价”的东西感兴趣。使用 Unicode 代码点,视觉上相同的“字符”可以以不止一种方式编码。例如,“Á”可以表示为预先组合的“Á”或分解的 A + ◌́(这就是示例中 composed.utf16decomposed.utf16 长度不同的原因)。值得一读的是this great article

            -[NSString isEqualToString:],根据documentation,逐个代码单元比较NSStrings代码单元,所以:

            [Á] != [A, ◌́]
            

            斯威夫特的字符串==compares characters by canonical equivalence

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

            在 swift 中,上面的示例将为字符串返回 true。这就是为什么-[NSString isEqualToString:] 不等同于 Swift 的 String ==。等效的纯 Swift 比较可以通过比较 String 的 UTF-16 视图来完成:

            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
            

            【讨论】:

              猜你喜欢
              • 2023-03-18
              • 1970-01-01
              • 2017-11-09
              • 1970-01-01
              • 1970-01-01
              • 2013-12-01
              • 2015-07-30
              • 2011-07-21
              • 1970-01-01
              相关资源
              最近更新 更多