> On 18 May 2016, at 11:56, Artyom Goncharov via swift-users
> <[email protected]> wrote:
>
> 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
> Best wishes,
> Artyom
> _______________________________________________
> swift-users mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users