Dictionary<AnyHashable: Any> 在 Swift 3 中 Any 可能持有 nil 值
Posted
技术标签:
【中文标题】Dictionary<AnyHashable: Any> 在 Swift 3 中 Any 可能持有 nil 值【英文标题】:Dictionary<AnyHashable: Any> where Any may hold nil value in Swift 3 【发布时间】:2016-12-12 21:40:16 【问题描述】:有人可以解释为什么这在 Swift 3 中有效吗?
var dict: [AnyHashable: Any]
let b: AnyObject? = nil
let c = b as Any
dict = ["a": "aa", "b": c]
如果我测试
dict["b"] == nil
它返回假。应该是对的吧?
【问题讨论】:
在 Swift 中使用nil
作为字典值是无稽之谈,因为根据定义将键设置为 nil
会删除该键。
我知道。关键是:不知何故,我得到了一个带有 nil
值的字典并且无法删除它,因为检查 dict[key] == nil
总是返回 false
你为什么不把它作为一个可选的并检查if let _ = dict["b"]
。这始终是 swift 中的首选检查
有趣...这里有太多的编译器魔法。 c
是 Any?
,而不是 nil
,因为 c
有一个值。但值是nil
。
通过dict[key] = nil
将其设置为 nil 确实会删除该值。但是,dict 可以将“可选”作为其类型。它会导致与下标语法混淆的行为,但您仍然可以执行类似dict.updateValue(nil, forKey: "a")
的操作来设置 nil 值。出于显而易见的原因,根本不推荐使用带有选项的 dict。
【参考方案1】:
您遇到了嵌套选项。如果字典拥有E
类型,则字典访问方法返回E?
类型的值,如果存在则返回值,或者为零。
在您的情况下,您创建了一个字典,其中的值是可选的。所以上面的E
类似于Any?
。这意味着getter的返回值为E?
,即Any??
在您的情况下,dict["b"]
返回一个非 nil 可选,包含值“nil”
将您的代码放在操场上并打印 dict["b"]
通过打印字符串 Optional(nil)
来确认这一点
【讨论】:
【参考方案2】:假设您使用的是最新的 Xcode,8.1 (8B62) 和 Swift 3.0.1。
包含nil
的Any
并不像简单的嵌套可选那么简单:
嵌套可选
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
返回true
。
Any
包含 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
变为false
,由 OP 编写。
您可以在Any
中检测到nil
,如下所示:
if let b = dict["b"] //<-check if `dict` contains value for "B"
if b as AnyObject === NSNull()
print("b is nil") //->b is nil
(这适用于 Swift 3.0.1,不适用于 Swift 3.0.0。)
【讨论】:
以上是关于Dictionary<AnyHashable: Any> 在 Swift 3 中 Any 可能持有 nil 值的主要内容,如果未能解决你的问题,请参考以下文章
无法访问 [AnyHashable:Any] 类型的值 - Swift 4
将 userInfo [AnyHashable: Any] 转换为 [String: Any]
无法使用“Any?”类型的索引为“[AnyHashable:Any]”类型的值下标
将 [Dictionary<String,Any?>] 转换为 [Dictionary<String,Any!>] ?迅速 3