【问题标题】:Dictionary<AnyHashable: Any> where Any may hold nil value in Swift 3Dictionary<AnyHashable: Any> 在 Swift 3 中 Any 可能持有 nil 值
【发布时间】: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。

标签: swift swift3 swift-dictionary


【解决方案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。)

    【讨论】:

      猜你喜欢
      • 2017-11-14
      • 2018-02-27
      • 2020-03-07
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      相关资源
      最近更新 更多