[swift-users] Dictionary with optional values

Jeremy Pereira jeremy.j.pereira at googlemail.com
Thu May 19 08:10:43 CDT 2016


> On 18 May 2016, at 11:56, Artyom Goncharov via swift-users <swift-users at swift.org> 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
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users



More information about the swift-users mailing list