简体   繁体   English

Swift(beta 3)“NSDictionary? 不符合协议'Equatable'“

[英]Swift (beta 3) “NSDictionary? does not conform to protocol 'Equatable'”

I've had a fair few warnings and errors in my Swift code since updating to the latest Xcode 6 DP3. 自从更新到最新的Xcode 6 DP3以来,我在Swift代码中遇到了一些警告和错误。 Most have been resolved by adopting the newly changed syntax however there is one error which seems strange. 大多数已通过采用新更改的语法解决,但有一个错误似乎很奇怪。

The following code gives the error Type 'NSDictionary?' does not conform to protocol 'Equatable' 以下代码给出错误Type 'NSDictionary?' does not conform to protocol 'Equatable' Type 'NSDictionary?' does not conform to protocol 'Equatable' : Type 'NSDictionary?' does not conform to protocol 'Equatable'

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

Does anyone have a solution? 有没有人有办法解决吗? I'm probably overlooking something simple here..! 我可能会在这里忽略一些简单的东西..!

Thanks 谢谢

There is a regression in Beta 3 causing that Optional<T> cannot be compared with nil if T is not Equatable or Comparable . Beta 3中存在回归导致如果T不是EquatableComparable ,则Optional<T>无法与nil Comparable

It's a bug caused by the removal of the _Nil type for which the equality operators were defined. 这是由删除定义了相等运算符的_Nil类型引起的错误。 nil is now a literal. nil现在是一个常量。 The bug has been confirmed by Chris Lattner on Apple Dev Forums 该问题已由Chris Lattner在Apple Dev论坛上得到证实

Some workarounds: 一些解决方法:

You can still use .getLogicValue() 你仍然可以使用.getLogicValue()

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

or directly 或直接

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

or you can use the "Javascript object to boolean" solution 或者您可以使用“Javascript对象布尔”解决方案

var bool = !!launchOptions

(first ! calls the getLogicValue and negates, the second ! negates again) (首先!调用getLogicValue并取消,第二个!再次否定)

or, you can define those equality operators by yourself until they fix it: 或者,您可以自己定义这些相等运算符,直到它们修复它:

//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()
}

Example: 例:

class A {
}

var x: A? = nil

if x == nil {
    println("It's nil!")
}
else {
    println("It's not nil!")
}

However, this workaround might cause other subtle problems (it probably works similarily to the _Nil type in Beta 2 which was removed because it was causing problems...). 但是,这种解决方法可能会导致其他微妙的问题(它可能_Nil Beta 2中的_Nil类型,因为它导致了问题而被删除了...)。

The release notes of XCode 6 Beta 5 state the following: XCode 6 Beta 5的发行说明如下:

Optionals no longer conform to the BooleanType (formerly LogicValue) protocol, so they may no longer be used in place of boolean expressions (they must be explicitly compared with v != nil). Optionals不再符合BooleanType(以前的LogicValue)协议,因此它们可能不再用于代替布尔表达式(它们必须与v!= nil明确比较)。 This resolves confusion around Bool? 这解决了Bool的混乱局面? and related types, makes code more explicit about what test is expected, and is more consistent with the rest of the language. 和相关类型,使代码更明确地说明预期的测试,并且与语言的其余部分更加一致。

Note that ImplicitlyUnwrappedOptional still includes some BooleanType functionality. 请注意,ImplicitlyUnwrappedOptional仍包含一些BooleanType功能。 This !issue will be resolved in a future beta. 这个问题将在未来的测试版中得到解决。 (17110911)! (17110911)!

This means your previous approach should work now without any issues, just go back to it: 这意味着您之前的方法现在应该没有任何问题,只需返回它:

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

As @Sulthan figured out, this is a bug in the current beta release of the Swift compiler. 正如@Sulthan所知,这是Swift编译器当前测试版中的一个错误。 But note that an optional is itself a LogicValue that can be tested for its boolean value. 但请注意,可选的本身是一个LogicValue ,可以测试它的布尔值。 So you can simply write 所以你可以简单地写

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

without comparing to nil . 没有比较nil

This compiles for me but I'm not sure if it works as intended: 这为我编译,但我不确定它是否按预期工作:

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

This is most likely a side-effect by the change of nil to a literal in beta 3: 这很可能是在beta 3中将nil更改为文字的副作用:

• nil is now a literal in the language, not a global constant of _Nil type. •nil现在是语言中的文字,而不是_Nil类型的全局常量。 This change resolved a number of problems with nil; 这个改变解决了nil的一些问题; eg nil in a collection, nil converting to Any, etc. Types can now indicate that they are nil compatible by conforming to the NilLiteralConvertible protocol. 例如,集合中的nil,nil转换为Any等。类型现在可以通过符合NilLiteralConvertible协议来指示它们是零兼容的。 (16951729) (16951729)

For some reason it just complains when its an optional returned from indexing a dictionary, I have a feeling this will be fixed in the future. 由于某些原因,它只是在索引字典时返回一个可选项时抱怨,我觉得这将在以后修复。 Submit a bug report though! 提交错误报告!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM