Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImplicitlyUnwrappedOptional in init vs later

Tags:

swift

swift4

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")]
like image 615
allaire Avatar asked Nov 08 '22 07:11

allaire


1 Answers

In Swift 4.1, when you do:

var str: String!

str = "Hello"

var params: [String: Any] = [
    "foo": str
]

The ImplicitlyUnwrappedOptional (IUO) value is coerced to Any, 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 with Any.

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 an Optional value inside your dictionary instead, which will print as Optional("Hello").

There's more discussion of the above behaviour in this Q&A:

  • Why does implicitly unwrapped optional not unwrap in dictionary of type [String : Any]

When you do:

params["bar"] = str

You're using Dictionary's subscript(key: Key) -> Value?, which takes an Optional value – performing a removal if nil is passed, otherwise doing an insertion of the unwrapped value.

  • In Swift 4.1, the IUO value str will be implicitly converted to an Optional which can then be passed to the subscript.
  • In Swift 4.2, the IUO type has been removed, so str already is an Optional, 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. If str had been nil, no value for the key "bar" would have been inserted.

like image 75
Hamish Avatar answered Nov 14 '22 21:11

Hamish