一尘不染

Swift 3无法将符合协议的对象数组追加到该协议的集合中

swift

下面我粘贴了代码,您应该可以将这些代码粘贴到Swift 3游乐场中并查看错误。

我定义了一个协议并创建该类型的空数组。然后,我有一个符合我尝试附加到数组的协议的类,但出现以下错误。

protocol MyProtocol {
    var text: String { get }
}

class MyClass: MyProtocol {
    var text = "Hello"
}
var collection = [MyProtocol]()
var myClassCollection = [MyClass(), MyClass()]
collection.append(myClassCollection)

argument type '[MyClass]' does not conform to expected type 'MyProtocol'

请注意,集合+ = myClassCollection返回以下错误:

error: cannot convert value of type '[MyProtocol]' to expected argument type 'inout _'

这在早期的Swift版本中有效。

到目前为止,我发现的唯一解决方案是迭代每个元素并将其添加到新数组中,如下所示:

for item in myClassCollection {
    collection.append(item)
}

任何帮助表示赞赏,谢谢!

编辑

如下所示的解决方案是:

collection.append(contentsOf: myClassCollection as [MyProtocol])

真正的问题是,当您丢失“ as [MyProtocol]”时,会产生误导性的编译器错误

编译器错误为:

error: extraneous argument label 'contentsOf:' in call
collection.append(contentsOf: myClassCollection)

此错误导致用户contentsOf:从代码中删除,然后导致我首先提到的错误。


阅读 245

收藏
2020-07-07

共1个答案

一尘不染

append(_ newElement: Element)追加一个元素。你想要的是append(contentsOf newElements: C)

但是您必须 [MyClass]数组[MyProtocol]显式 转换 为:

collection.append(contentsOf: myClassCollection as [MyProtocol])
// or:
collection += myClassCollection as [MyProtocol]

如在Swift中使用协议时在类型转换中所述,这会将每个数组元素包装到一个容纳“符合MyProtocol” 的盒子中,而不仅仅是对数组的重新解释。

编译器自动为单个值执行此操作(这就是为什么

for item in myClassCollection {
    collection.append(item)
}

编译),但不能用于数组。在早期的Swift版本中,您甚至无法使用强制转换整个数组as [MyProtocol],而必须强制转换每个单独的元素。

2020-07-07