下面我粘贴了代码,您应该可以将这些代码粘贴到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:从代码中删除,然后导致我首先提到的错误。
contentsOf:
append(_ newElement: Element)追加一个元素。你想要的是append(contentsOf newElements: C)。
append(_ newElement: Element)
append(contentsOf newElements: C)
但是您必须 将[MyClass]数组[MyProtocol]显式 转换 为:
[MyClass]
[MyProtocol]
collection.append(contentsOf: myClassCollection as [MyProtocol]) // or: collection += myClassCollection as [MyProtocol]
如在Swift中使用协议时在类型转换中所述,这会将每个数组元素包装到一个容纳“符合MyProtocol” 的盒子中,而不仅仅是对数组的重新解释。
MyProtocol
编译器自动为单个值执行此操作(这就是为什么
编译),但不能用于数组。在早期的Swift版本中,您甚至无法使用强制转换整个数组as [MyProtocol],而必须强制转换每个单独的元素。
as [MyProtocol]