arrays - 为什么 Swift 编译器无法确定混合类型数组中元素的类型?

标签 arrays swift cocoa cocoa-touch

这是我的代码:

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,或者是因为您导入了 UIKitCocoa 每个都导入 Foundation

导入Foundation时,混合数组被视为NSArray,这与[AnyObject]本质上相同。这意味着放入该数组的任何内容都必须是 的实例。由于 String 是结构,而 IntDouble 是基本类型,因此它们不是类。 String 被提升为 NSStringIntDouble 被包裹在 NSNumber.

如果打印出值的 dynamicTypes,您可以看到这一点:

print(mixedTypeArray[0].dynamicType)  // _NSContiguousString
print(mixedTypeArray[1].dynamicType)  // __NSCFNumber.Type
print(mixedTypeArray[2].dynamicType)  // __NSCFNumber.Type

_NSContiguousStringNSString 的内部表示。 __NSCFNumber.TypeNSNumber 的内部表示。

但数组本身只包含一种类型:AnyObject

当你这样做时:

let elementOfApparentlyUnknownType = mixedTypeArray[0] // AnyObject

然后该值的类型为 AnyObject,因为这就是数组存储的内容。 Swift 看不到该项目真的是一个 NSString,因为这是一个运行时考虑因素。在编译时,Swift 不会跟踪您将 String 放在该数组的 0 位置。它只知道该数组的类型为 NSString(也称为 [AnyObject])。

在 Swift 中,变量的类型在编译时是已知的。在任何时候,您都可以Option-点击任何变量来查看它的类型。出于这个原因,Swift 能做的最好的事情就是让你的变量成为 AnyObject,因为在编译时它不知道数组中值的底层类型。

您可以将数组声明为 [Any] 类型,然后您的值的 dynamicTypes 将保持为 StringIntDouble。但是,任何数组访问都将产生一个 Any 类型的变量。

Swift 不会将数组推断为[Any] 类型。如果您明确要求,它只会给您。作为一般设计规则,如果您发现自己使用 Any,则您可能正在以错误的方式解决问题。

关于arrays - 为什么 Swift 编译器无法确定混合类型数组中元素的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38111744/

相关文章:

java - 计算非素数

arrays - 串联排序两个数组的奇怪案例

swift - 提供获取当前速度的简单方法(实现速度计)

swift - 获取特定区域的节点列表?

objective-c - 高效的核心数据递归

objective-c - 将 NSImage* 转换为 CGImageRef?

php - 将 PHP 多维数组转换为 Postgres HStore

c - 字符串的第一个非重复字符

ios - 如何使 View 始终在应用程序的屏幕上可见?

macos - 快速识别哪个 NSTextFields 正在编辑