Reputation: 33
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?
Upvotes: 3
Views: 11878
Reputation: 47906
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:
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 .)
Upvotes: 1
Reputation: 29538
You're running into nested optionals. If a dictionary holds a type E
, then the dictionary access method returns a value of type E?
, either the value if it exists, or nil.
In your case, you've created a dictionary where the value is an optional. So the E
above is something like Any?
. This means the return value of the getter is E?
i.e., Any??
In your case, dict["b"]
returns a non-nil optional, containing the value 'nil'
Putting your code in a playground and printing dict["b"]
confirms this by printing the string Optional(nil)
Upvotes: 2