有人可以解释为什么这段代码会抛出错误吗?
class Base {}
class SubclassOfBase: Base {}
let baseItems = [Base](count: 1, repeatedValue: Base())
let subclassItems = [SubclassOfBase](count: 3, repeatedValue: SubclassOfBase())
var items = [Base]()
items.append(SubclassOfBase()) //OK
items.appendContentsOf(baseItems) //OK
items.appendContentsOf(subclassItems) //cannot invoke with argument of type [SubclassOfBase]
items.append(subclassItems.first!) //OK
接下来的问题:添加子类元素的唯一方法是在for循环中逐个添加它们吗?
答案 0 :(得分:11)
如果您检查标题:
public mutating func append(newElement: Element)
public mutating func appendContentsOf<C : CollectionType where C.Generator.Element == Element>(newElements: C)
注意类型说明符的区别。虽然append
允许您添加Element
的任何内容,即包括子类,但appendContentsOf
强制您使用具有完全相同元素类型的数组(不允许子类)。< / p>
它适用于:
let subclassItems = [Base](count: 3, repeatedValue: SubclassOfBase())
我认为这是一个bug,因为这可以通过改进函数头来轻松修复(好吧,这也需要where
子句的扩展,因为现在检测通用子类型是不可能的。)
一些可能的解决方法:
直接追加每个项目
subclassItems.forEach {items.append($0)}
为数组声明一个帮助方法(适用于Array
,而不适用于通用CollectionType
)
extension Array {
public mutating func appendContentsOf(newElements: [Element]) {
newElements.forEach {
self.append($0)
}
}
}
直播
items.appendContentsOf(subclassItems as [Base])