在Xcode 8发行版中,我发现了一个奇怪的场景。
这是代码,
let implicitlyUnwrappedOptionalString: String! = "implicitlyUnwrappedOptionalString" let foo = implicitlyUnwrappedOptionalString print(implicitlyUnwrappedOptionalString) print(foo)
结果如下:
implicitlyUnwrappedOptionalString Optional("implicitlyUnwrappedOptionalString")
上面的这些表明,当我为没有显式类型的变量分配一个 隐式解包的optional时 ,该类型将被推断为一个可选类型,而不是它最初的类型,也就是 隐式解开的optional 。
我的Xcode已更新至8。任何人都可以验证Xcode 7.x中的行为吗?
更改是由于Swift版本更改还是Xcode?
这是SE-0054废除ImplicitlyUnwrappedOptional类型的结果,该类型已在Swift 3中实现。从该提案中摘录(添加了重点):
但是,外观!在属性或变量声明的类型的末尾不再指示该声明具有IUO类型;相反,它指示(1)声明具有可选类型,并且(2)声明具有指示其值可以隐式强制的属性。… 如果可以使用强可选类型对表达式进行显式类型检查,则它将是。 但是,如果需要,类型检查器将转为强制使用可选。此行为的结果是,引用指向声明为T!的值的任何表达式的结果。将是T型还是T?型。例如,在以下代码中: let x: Int! = 5 let y = x let z = x + 0 …x被声明为IUO,但是由于y类型的初始化程序正确检查为可选变量,因此y将绑定为Int?类型。但是,z的初始值设定项不会将x声明为可选项(没有+的重载是可选项)的类型检查,因此编译器会强制执行可选项,并将初始值设定项检查为Int。
但是,外观!在属性或变量声明的类型的末尾不再指示该声明具有IUO类型;相反,它指示(1)声明具有可选类型,并且(2)声明具有指示其值可以隐式强制的属性。…
如果可以使用强可选类型对表达式进行显式类型检查,则它将是。 但是,如果需要,类型检查器将转为强制使用可选。此行为的结果是,引用指向声明为T!的值的任何表达式的结果。将是T型还是T?型。例如,在以下代码中:
let x: Int! = 5 let y = x let z = x + 0
…x被声明为IUO,但是由于y类型的初始化程序正确检查为可选变量,因此y将绑定为Int?类型。但是,z的初始值设定项不会将x声明为可选项(没有+的重载是可选项)的类型检查,因此编译器会强制执行可选项,并将初始值设定项检查为Int。
在您的情况下,作业
let foo = implicitlyUnwrappedOptionalString
foo如let y = x 建议中的示例所示,使之具有较强的可选性。
foo
let y = x
您 可以foo通过添加显式类型注释 来 创建IUO
let foo: String! = implicitlyUnwrappedOptionalString
但通常,您应该尝试摆脱代码中的IUO,如同一建议中所述:
除了一些特定的情况外,可选选项始终是更安全的选择,我们希望鼓励人们使用它们而不是IUO。