Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicitly unwrapped optional assign in Xcode 8

Tags:

xcode

ios

swift

In Xcode 8 release version, i found a strange scene.

Here is the code,

let implicitlyUnwrappedOptionalString: String! = "implicitlyUnwrappedOptionalString"
let foo = implicitlyUnwrappedOptionalString

print(implicitlyUnwrappedOptionalString)
print(foo)

and here is the result:

implicitlyUnwrappedOptionalString
Optional("implicitlyUnwrappedOptionalString")

These above shows that when i assign a implicitly unwrapped optional to a variable without a explicit type, the type will be inferred to an optional type, not the type which it originally is, aka implicitly unwrapped optional.

My Xcode has been updated to 8. Anyone can verify the behavior in Xcode 7.x?

The change is due to the Swift version changing or the Xcode?

like image 273
liuwin7 Avatar asked Sep 22 '16 08:09

liuwin7


1 Answers

This is a consequence of SE-0054 Abolish ImplicitlyUnwrappedOptional type which has been implemented in Swift 3. Extract from that proposal (emphasis added):

However, the appearance of ! at the end of a property or variable declaration's type no longer indicates that the declaration has IUO type; rather, it indicates that (1) the declaration has optional type, and (2) the declaration has an attribute indicating that its value may be implicitly forced. ...

If the expression can be explicitly type checked with a strong optional type, it will be. However, the type checker will fall back to forcing the optional if necessary. The effect of this behavior is that the result of any expression that refers to a value declared as T! will either have type T or type T?. For example, in the following code:

let x: Int! = 5
let y = x
let z = x + 0

… x is declared as an IUO, but because the initializer for y type checks correctly as an optional, y will be bound as type Int?. However, the initializer for z does not type check with x declared as an optional (there's no overload of + that takes an optional), so the compiler forces the optional and type checks the initializer as Int.

In your case, the assignment

let foo = implicitlyUnwrappedOptionalString

makes foo a strong optional, as in the example let y = x from the proposal.

You could make foo an IUO by adding an explicit type annotation

let foo: String! = implicitlyUnwrappedOptionalString

but generally you should try to get rid from IUOs in your code, as stated in the same proposal:

Except for a few specific scenarios, optionals are always the safer bet, and we’d like to encourage people to use them instead of IUOs.

like image 66
Martin R Avatar answered Nov 12 '22 12:11

Martin R