Swift 3 incorrect string interpolation with implicitly unwrapped Optionals -


why implicitly unwrapped optionals not unwrapped when using string interpolation in swift 3?

example: running following code in playground

var str: string! str = "hello"  print("the following should not printed optional: \(str)") 

produces output:

the following should not printed optional: optional("hello") 

of course can concatenate strings + operator i'm using string interpolation pretty everywhere in app doesn't work anymore due (bug?).

is bug or did intentionally change behaviour swift 3?

as per se-0054, implicitlyunwrappedoptional no longer distinct type. instead, it's same type regular optional – has attribute allows compiler force unwrap in situations cannot type checked one.

as proposal says (emphasis mine):

if expression can explicitly type checked strong optional type, be. however, type checker fall forcing optional if necessary. effect of behavior the result of expression refers value declared t! either have type t or type t?.

what means when comes type inference, compiler favour typing implicitly unwrapped optional optional, rather force unwrapping it. however, behaviour overridden when explicit type annotation supplied.

when comes string interpolation, under hood compiler uses initialiser _expressiblebystringinterpolation protocol in order evaluate string interpolation segment:

/// creates instance containing appropriate representation /// given value. /// /// not call initializer directly. used compiler /// each string interpolation segment when use string interpolation. /// example: /// ///     let s = "\(5) x \(2) = \(5 * 2)" ///     print(s) ///     // prints "5 x 2 = 10" /// /// initializer called 5 times when processing string literal /// in example above; once each following: integer `5`, /// string `" x "`, integer `2`, string `" = "`, , result of /// expression `5 * 2`. /// /// - parameter expr: expression represent. init<t>(stringinterpolationsegment expr: t) 

as initialiser uses generic parameter (no explicit type annotation), compiler able infer parameter t of type optional implicitly unwrapped optional input, therefore meaning won't force unwrapped.

conversely, if take example print() takes any parameter (an explicit, albeit abstract type annotation), compiler won’t able infer iuo input of type optional, , therefore will implicitly force unwrapped.

if wish iuo force unwrapped when used in string interpolation, can use force unwrap operator !:

var str: string! str = "hello"  print("the following should not printed optional: \(str!)") 

or can cast non-optional type (in case string) in order force compiler implicitly force unwrap you:

print("the following should not printed optional: \(str string)") 

both of which, of course, crash if str nil.


Comments

Popular posts from this blog

php - How to add and update images or image url in Volusion using Volusion API -

javascript - IE9 error '$'is not defined -