【发布时间】:2016-08-03 06:17:27
【问题描述】:
编辑:这在 Swift 3 中工作得非常好,我们现在都应该使用它 :)
如果我有两个协议X 和Y,其中Y 实现X,为什么我不能将Y 的数组分配给[X] 类型的变量?
更奇怪的是,我可以将它一个一个转换成一个 X 数组,并且编译得很好。
protocol X { }
protocol Y: X { }
// Make a test array of Y
extension String: Y { }
let a: [Y] = [ "Hello" ]
// Make it into an array of X - this works absolutely fine
let b: [X] = [ a[0] as X ]
// Why won't this cast work?
let c: [X] = a as [X]
我认为 Y 做了 X 可以做的所有事情,这个赋值应该没问题(是的,我丢失了一些类型信息,但它至少应该编译!)
有什么想法吗?
编辑:current answer 指出,如果您使用可变数组,这是一件危险的事情——我没有得到但现在这样做了 :) 但是,如果我的数组都是不可变的,为什么 Swift 不让这会发生吗?即使c 是一个可变数组(即var c = a as [X]),为什么Swift 不会复制它,而让a 保持原样?
【问题讨论】:
-
Swift 泛型是不变的。不确定您是否可以在 swift 中使用协变泛型。
-
这段代码的问题在于,您可以将
Z添加到同样源自X 的层次结构中。现在您的数组同时具有Y和Z,即使Z不是Y的子类型。 -
@LukaJacobowitz:我认为这不是问题所在。事实上,您仍然可以单独附加符合
Y的不同类型。例如。struct Z: X {};b.append(Z())。现在b包含String类型的元素和Z类型的元素。编译器对此很好。 -
我知道,但考虑一下:` (a as [X]).append(Z())` 现在您将 Z 添加到 Y 数组中
-
顺便说一句,这在 Swift 3 中运行良好