2016-09-22 38 views
7

我很困惑:斯威夫特 - 字典值設置爲nil,混亂

讓我們創建一個字典:

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] 

這是怎麼回事?和順便說一句,爲什麼迅速讓我們刪除鍵與它們設置爲nil,而不是與

d.removeValue(forKey: "foo") 

堅持?

+0

什麼是你斯威夫特版本開始討論? – iMuzahid

+0

我正在運行swift 3 – Guig

+0

在Objective-C中,字典中的所有鍵和值都不能爲「nil」。 Swift字典應該類似地工作。只是不要使用可選值;-) – vadian

回答

1

要刪除一個關鍵的[A: B]類型的字典,你需要到其值設置爲的值nil

B?類型的元素。例如:

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 = StringB = Any?

除去關聯foo鍵/值,我們需要設置值爲nilB? = Any??的值:

let v: Any?? = nil 
d["foo"] = v // d is now [:] 

當我們做

d["foo"] = nil 

的是,這裏nil澆鑄到Any??會發生什麼,而不是Any?,所以它實際上是從做

let v: Any? = nil 
d["foo"] = v // d is still ["foo": nil] 

不同的,這就是爲什麼結果不同。

感謝@sliwinski與蘋果該鏈接我們https://developer.apple.com/swift/blog/?id=12

1
/// 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情況下,似乎有在斯威夫特實現中的錯誤,至少到版本Apple Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1)

Btw。當從Dictionary所有元素被移除的Dictionarytype仍然正確識別

let x: String? = nil 
d["foo"] = x // d is now [:] 
let m = Mirror(reflecting: d) // Mirror for Dictionary<String, Optional<Any>> 

我讓自己添加錯誤斯威夫特郎鹹平:https://bugs.swift.org/browse/SR-3286

+0

感謝您的迴應並打開了該錯誤。我很好奇看到他們說什麼 – Guig