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

时间:2016-12-12 07:41:41

标签: arrays swift swift3 protocols

下面我已经粘贴了您应该能够粘贴到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:,然后导致我首次提到的错误。

2 个答案:

答案 0 :(得分:10)

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

但是你有 [MyClass]数组明确转换为[MyProtocol]

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

正如Type conversion when using protocol in Swift中所解释的那样 将每个数组元素包装成一个包含“符合MyProtocol的东西”的框,这不仅仅是一个重新解释 数组。

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

的原因)
for item in myClassCollection {
    collection.append(item)
}

编译)但不是数组。在早期的Swift版本中,你 甚至无法使用as [MyProtocol]投射整个数组,你 不得不施展每一个元素。

答案 1 :(得分:0)

当集合只期望单个项目时,您尝试追加数组。例如,将集合更改为此编译:

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)