简体   繁体   English

Swift编译器为什么无法找出混合类型数组中元素的类型?

[英]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 ,或者是因为你进口UIKitCocoa每其中进口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是结构,而IntDouble是基本类型,因此它们不是类。 The String gets promoted to NSString , and the Int and Double get wrapped in NSNumber . String提升为NSString ,并将IntDouble封装为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 . _NSContiguousStringNSString的内部表示。 __NSCFNumber.Type is an internal representation of NSNumber . __NSCFNumber.TypeNSNumber的内部表示。

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将保持StringIntDouble 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.

相关问题 将混合类型范围存储到数组 - Storing Mixed-Type Range to Array 为什么Swift有时会将混合类型数组视为单个类型数组? - Why does Swift Treat a Mixed Type Array as a Single Type Array Sometimes? 无法弄清楚如何附加到数组(结构内)(Swift) - Can't figure out how to append to an array (within a struct) (Swift) 为什么我不能访问此void类型数组的第二个元素 - Why can't I access the second element of this void type array 进入“ for”循环时,Array [0]正在更改,无法弄清原因 - Array[0] is changing while entering the “for” loop, can't figure out why 无法弄清楚为什么我的程序不打印数组内容 - Can't figure out why my program is not printing contents of array 弄清楚数组类型来比较java中的数组 - figure out array type to compare arrays in java 当元素明显受限时,为什么Swift编译器会在推断我的通用元素类型时抛出错误? - Why does the Swift Compiler throw an error on inferring the type of my Generic Element when the Element is clearly constrained? 当元素类型是协议 [Swift] 时,无法在通用 Array 类上调用扩展方法 - Can't call extension method on generic Array class when element type is a Protocol [Swift] 我们如何在 swift 中从 [AnyObject] 类型数组中找到一个元素 - How we can find an element from [AnyObject] type array in swift
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM