Why are implicitly unwrapped strings not unwrapped when using string interpolation in Swift 3?
Running the following code in the playground
var str: String!
str = "Hello"
print("The following should not be printed as an optional: \(str)")
The following should not be printed as an optional: Optional("Hello")
As per SE-0054,
ImplicitlyUnwrappedOptional is no longer a distinct type. Instead, it's now the same type as a regular
Optional – it just has an attribute that allows the compiler to force unwrap it in situations where it cannot be type checked as one.
As the proposal says (emphasis mine):
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
With string interpolation, an implicitly unwrapped optional (note this doesn't just apply to
String!) can be treated as a strong optional (as you can use string interpolation with any type) – therefore the compiler will favour treating it as such, and not force unwrap it.
If you wish for it to be force unwrapped, then you can use the force unwrap operator
var str: String! str = "Hello" print("The following should not be printed as an optional: \(str!)")
or you can cast to
String in order to force the compiler to implicitly force unwrap it for you:
print("The following should not be printed as an optional: \(str as String)")
both of which, of course, will crash if