7

使用Xcode 7.1开发swift 2.2时有两种情况让我很困惑,请看下面的例子,谢谢

首先,在导入 Foundation 时,我声明了一个 testArray,其中包含两个项目,一个 Integer 类型 1 和一个 String 类型“hello”,我的问题是为什么 Swift 类型推断 testArray 到 Array(NSObject) 而不是 Array(Any)

import Foundation
let testArray = [1, "hello"] 
print(testArray.dynamicType) //testArray is Array<NSObject>

其次,当我删除 import Foundation 时,下面的代码无法编译,错误消息是“表达式类型不明确,没有更多内容”,我的问题是为什么 Swift 在这种情况下不对 Array(Any) 进行类型推断,谢谢求助

let testArray2 = [2, "world"]
print(testArray2) 
//can't compile, error message = "Type of expression is ambiguous without more content"
4

2 回答 2

9
/// The protocol to which all types implicitly conform.
public typealias Any = protocol<>

Any只是一个所有类型都隐式遵守的协议——它本身不是一个具体的类型。Swift 不能推断出非具体类型的数组,这就是为什么它无法推断出Any,但成功了NSObject( Intcan be bridged to NSNumber, Stringcan be bridged to NSString– 它们都继承自NSObject,这是一个具体类型)。

例如,考虑一下:

protocol Foo {}
struct Bar:Foo {}
struct Baz:Foo {}

let arr = [Bar(), Baz()] // error: Type of expression is ambiguous without more context

因为Foo是非具体类型,Swift 无法推断出它的数组。您必须明确告诉编译器您希望它的类型是什么:

let arr:[Foo] = [Bar(), Baz()]

您还将获得相同的行为AnyObject(因为它是所有都隐式遵守的协议 - 但仍然不是具体类型):

class Qux {}
class Fox {}

let a = [Qux(), Fox()] // error: Type of expression is ambiguous without more context

let a1:[AnyObject] = [Qux(), Fox()] // no error

为什么Swift 无法推断出非具体类型的数组很可能是由于该语言中非具体类型的现有限制——目前大多数非平凡操作都需要具体类型。有关示例,请参阅这个很棒的问答

但说实话,你真的应该更多地考虑你是否真的需要一个Any. 我想不出有一个数组的单一实际应用Any,因为一切都隐含地符合元素,所以必须保证它们什么都不做(你不能对可能是任何东西的东西调用特定方法)。当然你可以进行类型转换,但是恢复你一开始就抛弃的类型安全有什么意义呢?

您应该始终尽可能地指定类型。您可以为您的值构建一个包装器——这可以是简单struct地包装几个属性,也可以是类型擦除,以便将非具体类型包装在伪具体类型中。至少,您应该考虑创建自己的数组元素符合的协议。

于 2016-05-04T10:52:25.227 回答
3

因为它不会自动识别数组Any

如果您将其定义为,它将起作用

let testArray2 :[Any] = [2, "world"]

Foundation导入NS API,它会自动将2toNSNumber"world"to转换为NSString,将其自动转换为数组NSObject

于 2016-05-04T10:10:43.873 回答