Search code examples
swiftswift3swift-dictionary

Dictionary<AnyHashable: Any> where Any may hold nil value in Swift 3


Can someone explain why this works in Swift 3?

var dict: [AnyHashable: Any]
let b: AnyObject? = nil
let c = b as Any

dict = ["a": "aa", "b": c]

If I test

dict["b"] == nil

It returns false. Is it supposed to be right?


Solution

  • Assuming you are using the latest Xcode, 8.1 (8B62) with Swift 3.0.1 .

    Any containing nil is not so easy as simple nested optional:

    Nested Optional

    var dictWithOptional: [String: AnyObject?] = [
        "a": "aa" as NSString,
        "b": nil,
    ]
    if let b = dictWithOptional["b"] { //<-check if `dict` contains value for "b"
        print(b) //->nil (with compiletime warning)
        print(b == nil) //->true
    }
    

    b == nil returns true.

    Any containing nil

    var dict: [AnyHashable: Any]
    let b: AnyObject? = nil
    let c = b as Any
    dict = ["a": "aa", "b": c]
    
    print(Array(dict.keys)) //->[AnyHashable("b"), AnyHashable("a")]
    if let b = dict["b"] { //<-check if `dict` contains value for "b"
        print(b) //->nil
        print(b == nil) //->false (with compiletime warning)
    }
    

    b == nil becomes false as written by the OP.

    You can detect nil in Any, with something like this:

    if let b = dict["b"] { //<-check if `dict` contains value for "B"
        if b as AnyObject === NSNull() {
            print("b is nil") //->b is nil
        }
    }
    

    (This works in Swift 3.0.1, not in Swift 3.0.0 .)