[英]Why can't the Swift compiler figure out the type of an element in a mixed-type array?
Here's my code: 这是我的代码:
let string: String = "hello"
let int: Int = 5
let double: Double = 3.14
let mixedTypeArray = [string, int, double]
let elementOfApparentlyUnknownType = mixedTypeArray[0] // AnyObject
I've very explicitly stated the types of each element in the mixed-type array mixedTypeArray
. 我已经非常明确地说明了混合类型数组mixedTypeArray
中每个元素的类型。 However, when grabbing the first element in the array, the compiler doesn't infer the element to be a String
. 但是,在获取数组中的第一个元素时,编译器不会将元素推断为String
。 Instead, it's of type AnyObject
. 而是类型为AnyObject
。
mixedTypeArray
is an NSArray
, since Swift's native Array
type doesn't allow storing elements of mixed types (unless they're all converted to AnyObject
, but that would lose type information). mixedTypeArray
是一个NSArray
,因为Swift的本机Array
类型不允许存储混合类型的元素(除非将它们全部转换为AnyObject
,但这会丢失类型信息)。 But if NSArray
is cool with storing elements of different types, why is mixedTypeArray[0]
of type AnyObject
? 但是,如果NSArray
凉爽与存储不同类型的元素,这是为什么mixedTypeArray[0]
的类型AnyObject
? Is NSArray
converting all the elements to AnyObject
behind the scenes? NSArray
是否将所有元素都在AnyObject
转换为AnyObject
? Is there any way to get the true type of mixedTypeArray[0]
at compile time? 有什么办法可以在编译时获取mixedTypeArray[0]
的真实类型吗? I'd like to avoid individually downcasting each element in mixedTypeArray
from AnyObject
to its actual type. 我想避免单独将mixedTypeArray
每个元素从AnyObject
转换为其实际类型。
Swift arrays only hold one type. Swift数组仅包含一种类型。 In pure Swift code, your example wouldn't even compile. 在纯Swift代码中,您的示例甚至无法编译。 You would get the error: error: type of expression is ambiguous without more context . 您会得到以下错误: 错误:如果没有更多上下文,则表达式的类型是不明确的 。
You code is compiling because you have Foundation
imported, either because you explicitly stated import Foundation
, or because you imported UIKit
or Cocoa
each of which imports Foundation
. 您的代码编译,因为你已经Foundation
进口的,或者是因为你明确规定import Foundation
,或者是因为你进口UIKit
或Cocoa
每其中进口Foundation
。
When Foundation
is imported, mixed arrays are treated as NSArray
which is essentially the same as [AnyObject]
. 导入Foundation
,将混合数组视为NSArray
,它与[AnyObject]
基本上相同。 This means anything that is put in that array has to be an instance of a class . 这意味着放在该数组中的任何内容都必须是一个类的实例。 Since String
is a struct, and Int
and Double
are primitive types, they are not classes. 由于String
是结构,而Int
和Double
是基本类型,因此它们不是类。 The String
gets promoted to NSString
, and the Int
and Double
get wrapped in NSNumber
. 将String
提升为NSString
,并将Int
和Double
封装为NSNumber
。
You can see this if you print out the dynamicTypes
of the values: 如果您打印出值的dynamicTypes
,则可以看到以下内容:
print(mixedTypeArray[0].dynamicType) // _NSContiguousString
print(mixedTypeArray[1].dynamicType) // __NSCFNumber.Type
print(mixedTypeArray[2].dynamicType) // __NSCFNumber.Type
_NSContiguousString
is an internal representation of an NSString
. _NSContiguousString
是NSString
的内部表示。 __NSCFNumber.Type
is an internal representation of NSNumber
. __NSCFNumber.Type
是NSNumber
的内部表示。
But the array itself only holds one type: AnyObject
. 但是数组本身仅持有一种类型: AnyObject
。
When you do: 当您这样做时:
let elementOfApparentlyUnknownType = mixedTypeArray[0] // AnyObject
then the value has the type AnyObject
because that is what the array is storing. 那么该值的类型为AnyObject
因为这是数组要存储的内容。 Swift does not look to see that the item is really an NSString
because that is a runtime consideration. Swift并没有看到该项目确实是NSString
因为这是运行时的考虑因素。 At compile time, Swift is not tracking that you put a String
in position 0
of that array. 在编译时,Swift没有跟踪您将String
放置在该数组的位置0
。 It only knows that that array has a type of NSString
(also known as [AnyObject]
). 它只知道该数组具有NSString
类型(也称为[AnyObject]
)。
The types of variables are known at compile time in Swift. 变量的类型在Swift编译时是已知的。 At any time, you can Option -click on any variable to see its type. 您可以随时在Option上单击任意变量以查看其类型。 For this reason, the best Swift can do is make your variable AnyObject
because at compile time it doesn't know the underlying types of the values in your array. 因此,最好的Swift可以做的就是将变量AnyObject
为变量,因为在编译时它不知道数组中值的基础类型。
You could have declared your array to be of type [Any]
and then the dynamicTypes
of your values would have remained String
, Int
, and Double
. 您可能已经声明数组为[Any]
类型,然后值的dynamicTypes
将保持String
, Int
和Double
。 But then, any array access would have yielded a variable of type Any
. 但是随后,任何数组访问都将产生类型为Any
的变量。
Swift will not infer an array to be of type [Any]
. Swift不会推断数组为[Any]
类型的数组。 It will only give you that if you explicitly ask for it. 如果您明确要求,它只会给您。 As a general design rule, if you find yourself using Any
, you probably are approaching the problem in the wrong way. 作为一般设计规则,如果发现自己使用Any
,则可能是错误地解决了该问题。
In Swift, all array elements must have the same type. 在Swift中,所有数组元素必须具有相同的类型。 In this case, all the array elements have type Any (not AnyObject, because you supplied one value of type Int). 在这种情况下,所有数组元素的类型都为Any(不是AnyObject,因为您提供了一个Int类型的值)。 The first array element is of type Any, not of type String. 第一个数组元素的类型为Any,而不是String。 The second is of type Any, not of type Int. 第二个是Any类型,而不是Int类型。 And so on. 等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.