简体   繁体   中英

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. 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' :

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 .

It's a bug caused by the removal of the _Nil type for which the equality operators were defined. nil is now a literal. The bug has been confirmed by Chris Lattner on Apple Dev Forums

You can still use .getLogicValue()

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

or directly

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

or you can use the "Javascript object to boolean" solution

var bool = !!launchOptions

(first ! calls the getLogicValue and negates, the second ! negates again)

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

The release notes of XCode 6 Beta 5 state the following:

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). This resolves confusion around 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. This !issue will be resolved in a future beta. (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. But note that an optional is itself a LogicValue that can be tested for its boolean value. So you can simply write

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

without comparing to 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:

• nil is now a literal in the language, not a global constant of _Nil type. This change resolved a number of problems with 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. (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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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