一尘不染

Xcode 8中隐式展开的可选分配

swift

在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?


阅读 253

收藏
2020-07-07

共1个答案

一尘不染

这是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。

在您的情况下,作业

let foo = implicitlyUnwrappedOptionalString

foolet y = x 建议中的示例所示,使之具有较强的可选性。

可以foo通过添加显式类型注释 创建IUO

let foo: String! = implicitlyUnwrappedOptionalString

但通常,您应该尝试摆脱代码中的IUO,如同一建议中所述:

除了一些特定的情况外,可选选项始终是更安全的选择,我们希望鼓励人们使用它们而不是IUO。

2020-07-07