这是我的代码:
let string: String = "hello"
let int: Int = 5
let double: Double = 3.14
let mixedTypeArray = [string, int, double]
let elementOfApparentlyUnknownType = mixedTypeArray[0] // AnyObject
我已经非常明确地说明了混合类型数组 mixedTypeArray
中每个元素的类型。但是,当获取数组中的第一个元素时,编译器不会将该元素推断为 String
。相反,它是 AnyObject
类型。
mixedTypeArray
是一个 NSArray
,因为 Swift 的原生 Array
类型不允许存储混合类型的元素(除非它们都被转换到 AnyObject
,但这会丢失类型信息)。但是,如果 NSArray
很适合存储不同类型的元素,为什么 mixedTypeArray[0]
是 AnyObject
类型的呢? NSArray
是否在幕后将所有元素转换为 AnyObject
?有什么方法可以在编译时得到 mixedTypeArray[0]
的真实类型吗?我想避免将 mixedTypeArray
中的每个元素从 AnyObject
单独向下转换为其实际类型。
最佳答案
Swift 数组只包含一种类型。在纯 Swift 代码中,您的示例甚至无法编译。您会收到错误:错误:表达式类型不明确,没有更多上下文。
您的代码正在编译,因为您导入了 Foundation
,或者是因为您明确声明了 import Foundation
,或者是因为您导入了 UIKit
或 Cocoa
每个都导入 Foundation
。
导入Foundation
时,混合数组被视为NSArray
,这与[AnyObject]
本质上相同。这意味着放入该数组的任何内容都必须是类 的实例。由于 String
是结构,而 Int
和 Double
是基本类型,因此它们不是类。 String
被提升为 NSString
,Int
和 Double
被包裹在 NSNumber
.
如果打印出值的 dynamicTypes
,您可以看到这一点:
print(mixedTypeArray[0].dynamicType) // _NSContiguousString
print(mixedTypeArray[1].dynamicType) // __NSCFNumber.Type
print(mixedTypeArray[2].dynamicType) // __NSCFNumber.Type
_NSContiguousString
是 NSString
的内部表示。 __NSCFNumber.Type
是 NSNumber
的内部表示。
但数组本身只包含一种类型:AnyObject
。
当你这样做时:
let elementOfApparentlyUnknownType = mixedTypeArray[0] // AnyObject
然后该值的类型为 AnyObject
,因为这就是数组存储的内容。 Swift 看不到该项目真的是一个 NSString
,因为这是一个运行时考虑因素。在编译时,Swift 不会跟踪您将 String
放在该数组的 0
位置。它只知道该数组的类型为 NSString
(也称为 [AnyObject]
)。
在 Swift 中,变量的类型在编译时是已知的。在任何时候,您都可以Option-点击任何变量来查看它的类型。出于这个原因,Swift 能做的最好的事情就是让你的变量成为 AnyObject
,因为在编译时它不知道数组中值的底层类型。
您可以将数组声明为 [Any]
类型,然后您的值的 dynamicTypes
将保持为 String
,Int
和 Double
。但是,任何数组访问都将产生一个 Any
类型的变量。
Swift 不会将数组推断为[Any]
类型。如果您明确要求,它只会给您。作为一般设计规则,如果您发现自己使用 Any
,则您可能正在以错误的方式解决问题。
关于arrays - 为什么 Swift 编译器无法确定混合类型数组中元素的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38111744/