【问题标题】:Swift (beta 3) "NSDictionary? does not conform to protocol 'Equatable'"Swift(beta 3)“NSDictionary?不符合协议'Equatable'”
【发布时间】:2014-08-05 16:57:52
【问题描述】:

自从更新到最新的 Xcode 6 DP3 后,我的 Swift 代码中出现了相当多的警告和错误。大多数已经通过采用新更改的语法得到解决,但是有一个错误似乎很奇怪。

以下代码给出错误Type 'NSDictionary?' does not conform to protocol 'Equatable'

if (launchOptions != nil && launchOptions![UIApplicationLaunchOptionsRemoteNotificationKey] != nil) {

有人有解决办法吗?我可能在这里忽略了一些简单的东西..!

谢谢

【问题讨论】:

    标签: ios swift nsdictionary


    【解决方案1】:

    Beta 3 中有一个回归,导致如果 T 不是 EquatableComparable,则 Optional<T> 无法与 nil 进行比较。

    这是由于删除了定义相等运算符的_Nil 类型而导致的错误。 nil 现在是文字。该错误已由 Chris Lattner 在Apple Dev Forums

    上确认

    一些解决方法:

    你仍然可以使用.getLogicValue()

    if launchOptions.getLogicValue() && ... {
    

    或直接

    if launchOptions && ... { //calls .getLogicValue()
    

    或者你可以使用“Javascript object to boolean”解决方案

    var bool = !!launchOptions
    

    (第一个!调用getLogicValue并否定,第二个!再次否定)

    或者,您可以自己定义这些相等运算符,直到他们修复它:

    //this is just a handy struct that will accept a nil literal
    struct FixNil : NilLiteralConvertible {
        static func convertFromNilLiteral() -> FixNil {
            return FixNil()
        }
    }
    
    //define all equality combinations
    func == <T>(lhs: Optional<T>, rhs: FixNil) -> Bool {
        return !lhs.getLogicValue()
    }
    
    func != <T>(lhs: Optional<T>, rhs: FixNil) -> Bool {
        return lhs.getLogicValue()
    }
    
    func == <T>(lhs: FixNil, rhs: Optional<T>) -> Bool {
        return !rhs.getLogicValue()
    }
    
    func != <T>(lhs: FixNil, rhs: Optional<T>) -> Bool {
        return rhs.getLogicValue()
    }
    

    例子:

    class A {
    }
    
    var x: A? = nil
    
    if x == nil {
        println("It's nil!")
    }
    else {
        println("It's not nil!")
    }
    

    但是,这种解决方法可能会导致其他微妙的问题(它可能与 Beta 2 中的 _Nil 类型类似,因为它会导致问题而被删除...)。

    【讨论】:

      【解决方案2】:

      XCode 6 Beta 5 的发行说明如下:

      Optionals 不再符合 BooleanType(以前的 LogicValue) 协议,因此它们可能不再用于代替布尔值 表达式(它们必须明确地与 v != nil 进行比较)。这个 解决围绕布尔的混乱?和相关类型,让代码更丰富 明确说明预期的测试,并且更符合 其他语言。

      注意 ImplicitlyUnwrappedOptional 仍然包含一些 BooleanType 功能。这个!问题将在未来的测试版中得到解决。 (17110911)!

      这意味着您以前的方法现在应该可以正常工作了,只需返回它:

      if (launchOptions != nil && launchOptions![UIApplicationLaunchOptionsRemoteNotificationKey] != nil) {
          // some code
      }
      

      【讨论】:

        【解决方案3】:

        正如@Sulthan 发现的那样,这是 Swift 编译器当前 beta 版本中的一个错误。 但请注意,可选项本身就是 LogicValue,可以对其进行测试 布尔值。所以你可以简单地写

        if launchOptions && launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] {
           // ...
        }
        

        没有与nil比较。

        【讨论】:

        • 感谢您的澄清,没想到我能做到这一点
        【解决方案4】:

        这是为我编译的,但我不确定它是否按预期工作:

        if launchOptions![UIApplicationLaunchOptionsRemoteNotificationKey] !== nil {}
        

        这很可能是在 beta 3 中将 nil 更改为文字的副作用:

        • nil 现在是语言中的文字,而不是 _Nil 的全局常量 类型。此更改解决了 nil 的许多问题;例如零 在集合中,nil 转换为 Any 等。类型现在可以指示 通过符合 NilLiteralConvertible 协议。 (16951729)

        由于某种原因,当它是从索引字典返回的可选选项时,它只会抱怨,我觉得这将在未来得到解决。不过提交错误报告!

        【讨论】:

          猜你喜欢
          • 2016-09-29
          • 2017-06-27
          • 1970-01-01
          • 1970-01-01
          • 2020-12-04
          • 1970-01-01
          • 2016-06-07
          • 2015-11-02
          相关资源
          最近更新 更多