每种类型都可以隐式提升为该类型的可选类型。这意味着当您施放时T?
to Any
很难知道它是否最初是T
或原本T?
(甚至T??
或者更糟)。最令人困惑的是Any
可以晋升为Any?
然后Any?
属于类型Any
,所以说出之间的区别Any
, Any?
, Any??
, and Any???
(等等)非常棘手,有时甚至是不可能的。
Any
是 Swift 中非常棘手的类型,几乎不应该使用。除了显式欺骗编译器(在一些非常奇特且脆弱的类型擦除器中)之外,我不知道在任何情况下它确实有意义Any
作为变量类型,并且绝对不是以下形式[Any]
。如果您创建了一个[Any]
,你已经走上了一条不会好走的坏路。
有极少数情况Any
作为函数参数类型是有意义的(print()
是最著名的),但它们在应用程序级代码中极为罕见。如果您发现自己需要Any
,你可能做错了什么,编译器会对此大惊小怪,并经常让你编写额外的内容as
代码以确保您所说的那些乱七八糟的事情是认真的。
只是为了给出一些具体的版本,当您输入时,可选性往往会丢失Any
。所以考虑一下这种情况:
let number: Int = 3
let optionalNumber: Int? = 3
let nilNumber: Int? = nil
let anyNumber = number as Any
let anyOptional = optionalNumber as Any
let anyNil = nilNumber as Any
if anyNumber is Int { print("number is Int")} // yes
if anyOptional is Int { print("optional number is Int")} // yes
if anyNil is Int { print("nil is Int")} // no
if anyNil is Int? { print("nil is Int?")}
// -> Error: Cannot downcast from 'Any' to a more optional type 'Int?'
Rats.
我们无法以同样的方式恢复我们的可选选项。当然,我们可以推广它:
if (anyNil as Any?) is Int? { print("nil is Int?") } // yes
但我们可以以这种方式推广任何东西,因为一切都隐含地是其自身的可选:
if (anyNumber as Any?) is Int? { print("number is Int?")} // also yes
所以,嗯。老鼠。我们真的不知道它最初是否是可选的。这很混乱,编译器警告你,如果你在这条路上走得太远,事情就会变得一团糟。 T->Any 有点神奇。 T->T?也是有点神奇。将这两种魔法结合起来,你最好清楚地知道自己在做什么。