编译器将swift中的TL;DR;个选项转换为Optional
个枚举实例,由于Any
可以映射到任何值,因此它可以用于存储选项.
Swift如何代表期权?它通过将SomeType?
映射到Optional
枚举的具体实现来实现:
Int? => Optional<Int>
String? => Optional<String>
Optional
的简化声明如下所示:
enum Optional<T> {
case none // nil
case some(T) // non-nil
}
现在,类型Any
的变量能够保存枚举值(或任何其他类型的值,甚至元类型信息),因此它应该能够保存例如nil
字符串,aka String?.none
,aka Optional<String>.none
.
让我们看看会发生什么.正如我们从Optional
声明中看到的那样,nil
对应于所有类型的.none
枚举情况:
nil == Optional<String>.none // true
nil == Optional<Int>.none // true
[Double]?.none == nil // also true
所以从理论上讲,你应该能够给一个声明为Any
的变量赋值nil
.不过,编译器不允许这样做.
为什么编译器不给Any
赋值呢?这是因为它无法推断.none
enum case 对应的类型.Optional
是泛型枚举,因此需要填充T
泛型参数,而普通nil
太宽.它应该使用哪个.none
值?Int
的那个,String
的那个,另一个?
这会给出一条支持上述段落的错误消息:
let nilAny: Any = nil // error: nil cannot initialize specified type 'Any' (aka 'protocol<>')
以下代码有效,相当于分配nil
:
let nilAny: Any = Optional<Int>.none
,因为上面的Any
变量实际上包含Optional
枚举的有效值.
间接分配也起作用,因为幕后nil
被转换为Optional<Type>.none
.
var nilableBool: Bool? // nilableBool has the Optional<Bool>.none value
var nilBoolAsAny: Any = nilableBool // the compiler has all the needed type information from nilableBool
与其他语言不同,Swift nil
对应一个具体的值.但它需要使用一个类型,以便编译器知道应该分配哪个Optional<T>.none
.我们可以将关键字视为提供了sugar语法.