I would like to understand why I don't get ImplicitlyUnwrappedOptional
when I do params["bar"] = str
but I get it when I declare params
with the same force unwrapped variable.
See the playground below:
import UIKit
var str: String!
str = "Hello"
var params: [String: Any] = [
"foo": str
]
params["bar"] = str
print(params)
// ["bar": "Hello", "foo": Swift.ImplicitlyUnwrappedOptional<Swift.String>.some("Hello")]
In Swift 4.1, when you do:
The
ImplicitlyUnwrappedOptional
(IUO) value is coerced toAny
, which is why it appears as an IUO inside your dictionary. It won't be force unwrapped, because the compiler will only force unwrap an IUO when the context demands its unwrapped type, which isn't the case withAny
.However the fact that you end up with an
ImplicitlyUnwrappedOptional
value is legacy behaviour. With the removal of the IUO type in Swift 4.2, you'll get anOptional
value inside your dictionary instead, which will print asOptional("Hello")
.There's more discussion of the above behaviour in this Q&A:
When you do:
You're using
Dictionary
'ssubscript(key: Key) -> Value?
, which takes anOptional
value – performing a removal ifnil
is passed, otherwise doing an insertion of the unwrapped value.str
will be implicitly converted to anOptional
which can then be passed to the subscript.str
already is anOptional
, which can be passed straight to the subscript without any intermediate conversions.In both cases,
str
's unwrapped value is inserted into the dictionary, which is why you see it as being unwrapped. Ifstr
had beennil
, no value for the key"bar"
would have been inserted.