Swift - the meaning of the word dictionary for confusion

I am very confused:

Create a dictionary:

var d = ["foo": nil] as [String: Any?] 

Now, if I want to remove the "foo" key, I can just do

 d["foo"] = nil // d is now [:] 

And another option could be:

 let x: String? = nil d["foo"] = x // d is now [:] 

But this behaves differently:

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

Similarly above (which I think is the same thing):

 d["foo"] = d["foo"] // d is still ["foo": nil] 

What's happening? And by the way, why quickly remove the keys by setting them to nil , sticking instead

 d.removeValue(forKey: "foo") 

?

+7
dictionary swift
source share
2 answers

To delete a key in a dictionary of type [A: B] , do you need to set its value to an element of type B? nil values

For example:

 var d = ["foo": 1] as [String: Int] let v: Int? = nil d["foo"] = v // d is now [:] 

or simply

 d["foo"] = nil // here nil is casted to Int? 

So, if now we have

 var d = ["foo": nil] as [String: Any?] 

A = String and B = Any?

to remove the key / value associated with foo , do we need to set the value for type B? = Any?? nil values:

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

What happens when we do

 d["foo"] = nil 

is that here nil entered in Any?? , not Any? therefore it actually differs from execution

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

and why the results are different.

Thanks to @sliwinski for opening the discussion with the apple that linked us to https://developer.apple.com/swift/blog/?id=12

+1
source share
 /// If you assign `nil` as the value for the given key, the dictionary /// removes that key and its associated value. 

This is an offer from the documentation, as you can see it by design. If this does not meet your needs, then you are doomed to use updateValue(value: Value, forKey: Hashable) , which also works more predictable.

I found that when using NSMutableDictionary instead of Dictionary it works as "expected"

 let ns = NSMutableDictionary(dictionary: d) let x: Any? = nil ns["foo"] = x // ns {} 

However, the case let x = Any? = nil let x = Any? = nil it seems that there is an error in the implementation of Swift, at least until the version of Apple Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1)

Btw. when all elements from the Dictionary are deleted, type of Dictionary is still correctly recognized

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

I allowed myself to add an error to Swift lang: https://bugs.swift.org/browse/SR-3286

+1
source share

All Articles