根据Apple Doc
Any类型表示任何类型的值,包括可选类型。 如果您使用可选值(其中一个值 类型为Any。如果确实需要使用可选的 值作为Any值,可以使用as运算符来显式转换 可选为Any,如下所示。
var things = [Any]()
things.append(3) // No warning
let optionalNumber: Int? = 3
things.append(optionalNumber) // Warning, even though Any also represents optional types.
things.append(optionalNumber as Any) // No warning
我们为什么需要将可选内容显式转换为Any
?
答案 0 :(得分:4)
每种类型都可以隐式提升为该类型的可选。这意味着当您将T?
投射到Any
时,很难知道它是最初的T
还是最初的T?
(甚至是T??
或更糟) 。最令人困惑的是,Any
可以提升为Any?
,并且Any?
的类型为Any
,因此要说出Any
和Any?
之间的区别,Any??
和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?'
老鼠。
我们无法以与放入可选方式相同的方式获得可选配件。我们当然可以对其进行推广:
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?也是一点魔术。结合这两种魔术,您最好确切地知道自己在做什么。