Swift - 将字典值设置为nil混淆

Gui*_*uig 8 dictionary swift

我很困惑:

让我们创建一个字典:

var d = ["foo": nil] as [String: Any?]
Run Code Online (Sandbox Code Playgroud)

现在,如果我想删除密钥"foo",我可以这样做

d["foo"] = nil // d is now [:]
Run Code Online (Sandbox Code Playgroud)

其他选择可能是:

let x: String? = nil
d["foo"] = x // d is now [:]
Run Code Online (Sandbox Code Playgroud)

但这表现不同:

let x: Any? = nil
d["foo"] = x // d is still ["foo": nil]
Run Code Online (Sandbox Code Playgroud)

与上述类似(我认为是相同的):

d["foo"] = d["foo"] // d is still ["foo": nil]
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事?顺便说一下,为什么swift让我们删除键并设置它们nil,而不是坚持

d.removeValue(forKey: "foo")
Run Code Online (Sandbox Code Playgroud)

小智 9

给定一个这样的字典:

dict: [String: String?] = []
Run Code Online (Sandbox Code Playgroud)

如果您nil像这样添加值:

dict["a"] = nil
Run Code Online (Sandbox Code Playgroud)

字典将是空的。但是,如果您添加nil这样的值:

dict["a"] = nil as String?
Run Code Online (Sandbox Code Playgroud)

字典不会空的。试试看...

func testDictionary() {
    var dict: [String: String?] = [:]

    dict["abc"] = nil
    print("dictionary is empty -> \(dict.isEmpty)") // -> true

    dict["abc"] = nil as String?
    print("dictionary is empty -> \(dict.isEmpty)") // -> false
}
Run Code Online (Sandbox Code Playgroud)

这似乎是非常奇怪的行为和微妙的差异。有人可以解释一下吗?


Gui*_*uig 3

要删除 type 字典中的键,您需要将其值设置为value[A: B]类型的元素B?nil

例如:

var d = ["foo": 1] as [String: Int]
let v: Int? = nil
d["foo"] = v // d is now [:]
Run Code Online (Sandbox Code Playgroud)

或者简单地

d["foo"] = nil // here nil is casted to Int?
Run Code Online (Sandbox Code Playgroud)

所以如果我们现在有

var d = ["foo": nil] as [String: Any?]
Run Code Online (Sandbox Code Playgroud)

A=StringB=Any?

要删除与 关联的键/值,我们需要将该值设置为value 的footype B?= :Any??nil

let v: Any?? = nil
d["foo"] = v // d is now [:]
Run Code Online (Sandbox Code Playgroud)

当我们这样做时会发生什么

d["foo"] = nil
Run Code Online (Sandbox Code Playgroud)

是herenil被转换为Any??而不是Any?,所以它实际上与doing不同

let v: Any? = nil
d["foo"] = v // d is still ["foo": nil]
Run Code Online (Sandbox Code Playgroud)

这就是结果不同的原因。

感谢 @sliwinski 开启与 Apple 的讨论,将我们链接到https://developer.apple.com/swift/blog/?id=12