我很困惑:
让我们创建一个词典:
var d = ["foo": nil] as [String: Any?]
现在,如果我想删除密钥"foo"
,我可以
d["foo"] = nil // d is now [:]
其他选择可能是:
let x: String? = nil
d["foo"] = x // d is now [:]
但这种行为有所不同:
let x: Any? = nil
d["foo"] = x // d is still ["foo": nil]
与上述类似(我认为是相同的):
d["foo"] = d["foo"] // d is still ["foo": nil]
发生了什么事?顺便说一句,为什么swift让我们删除键,将它们设置为nil
,而不是坚持
d.removeValue(forKey: "foo")
答案 0 :(得分:3)
/// If you assign `nil` as the value for the given key, the dictionary
/// removes that key and its associated value.
这是文档中的一句话,因为您可以看到它是设计的。如果这不符合您的需求,那么您注定要使用updateValue(value: Value, forKey: Hashable)
,这也更有效。
我发现,当您使用NSMutableDictionary
代替Dictionary
时,它的工作原理为"预期"
let ns = NSMutableDictionary(dictionary: d)
let x: Any? = nil
ns["foo"] = x // ns {}
然而,let x = Any? = nil
似乎在Swift实现中存在一个错误,至少是版本Apple Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1)
顺便说一下。删除Dictionary
中的所有元素后,type
的{{1}}仍然可以正确识别
Dictionary
我允许自己为Swift lang添加bug:https://bugs.swift.org/browse/SR-3286
答案 1 :(得分:1)
要删除类型为[A: B]
的字典中的键,您需要将其值设置为值为B?
nil
类型的元素
例如:
var d = ["foo": 1] as [String: Int]
let v: Int? = nil
d["foo"] = v // d is now [:]
或只是
d["foo"] = nil // here nil is casted to Int?
所以,如果我们现在有
var d = ["foo": nil] as [String: Any?]
A
= String
和B
= Any?
要删除与foo
相关联的键/值,我们需要将值设置为值B?
的{{1}} = Any??
类型:
nil
当我们做什么时会发生什么
let v: Any?? = nil
d["foo"] = v // d is now [:]
此处d["foo"] = nil
已投放到nil
而非Any??
,因此它与实际不同
Any?
这就是结果不同的原因。
感谢@sliwinski与苹果公开讨论,将我们与https://developer.apple.com/swift/blog/?id=12
联系起来答案 2 :(得分:0)
给出这样的字典:
dict: [String: String?] = []
如果您像这样添加nil
值:
dict["a"] = nil
字典将为空。但是,如果您像这样添加一个nil
值:
dict["a"] = nil as String?
字典将不为空。试试吧...
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
}
这似乎很奇怪,而且有细微的差别。有人可以解释吗?