[英]Swift 3 unable to append array of objects, which conform to a protocol, to a collection of that protocol
下面我粘贴了你应该能够粘贴到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'
请注意,collection + = 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:
然后导致我第一次提到的错误。
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]
整个数组,您必须转换每个单独的元素。
当集合只期望单个项目时,您尝试附加数组。 例如,将集合更改为此编译:
var collection = [[MyProtocol]]()
这里有一种方法可以将两个数组加在一起:
func merge<T: MyProtocol>(items: inout [T], with otherItems: inout [T]) -> [T] {
return items + otherItems
}
var myClassCollection = [MyClass(), MyClass()]
var myClassCollection2 = [MyClass(), MyClass()]
let combinedArray = merge(items: &myClassCollection, with: &myClassCollection2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.