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 中的首选检查 有趣...这里有太多的编译器魔法。 cAny?,而不是 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。

包含nilAny 并不像简单的嵌套可选那么简单:

嵌套可选

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]”类型的值下标

请求 Facebook 好友返回空

Dictionary 嵌套Dictionary

将 [Dictionary<String,Any?>] 转换为 [Dictionary<String,Any!>] ?迅速 3