Hi, here is the playground snippet:
var noOptDict = ["one": 1, "two": 2, "three": 3 ]
noOptDict["one"] = nil
noOptDict // “one” is gone
var optDict: [String: Int?] = ["one": 1, "two": 2, "three": nil]
optDict["one"] = nil
optDict // “one” is gone but “three” is still there
So the first dict instance works as it should, the second using opt values allows to store nil but deletes the key when you assign nil. Is it bug, feature, or both?
It’s correct behaviour, albeit confusing.
The type of a dictionary subscript is Optional<V> where V is the value type. If V is itself Optional<T> the the type of the subscript is Optional<Optional<T>> (T?? for shorthand).
Normally, when you assign a value in a context where an optional is required, the compiler implicitly wraps the value as an optional. i.e.
let foo: Int? = 2
let bar: Int? = nil
is compiled as if you wrote
let foo:Int? = Optional<Int>.Some(2)
let bar: Int? = Optional<Int>.None
When you have a nested optional type combined with the implicit conversion, the meaning of nil becomes ambiguous since it could either be the .None value of the outer type or a .Some value of the outer type wrapping the .None of the inner type.
let foo: Int?? = nil
could be
let foo: Int?? = Optional<Optional<Int>>.Some(Optional<Int>.None)
or
let foo: Int?? = Optional<Optional<Int>>.None
depending on where you stick the implicit wrapping. The Swift compiler chooses the latter.
You need to force the compiler to choose the former. The most terse way I have found to do this so far is
optDict["one"] = Int?.None
···
On 18 May 2016, at 11:56, Artyom Goncharov via swift-users <swift-users@swift.org> wrote:
Best wishes,
Artyom
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users