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

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

问题描述:

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

Below I have pasted code which you should be able to paste into a Swift 3 playground and see the error.

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

I have a protocol defined and create an empty array of that type. I then have a class which conforms to the protocol which I try to append to the array but I get the below error.

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返回以下错误:

Note that collection += myClassCollection returns the following error:

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

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

This was working in earlier versions of Swift.

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

The only solution I have found so far is to iterate and add each element to the new array like so:

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

任何帮助表示感谢,谢谢!

Any help appreciated, thanks!

编辑

解决方案如下:

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

真正的问题是,当您缺少作为[MyProtocol]"时,会产生误导性的编译器错误

The real issue is a misleading compiler error when you are missing "as [MyProtocol]"

编译器错误为:

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

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

This error causes users to remove contentsOf: from the code which then causes the error I first mentioned.

append(_ newElement: Element)附加单个元素. 您想要的是append(contentsOf newElements: C).

append(_ newElement: Element) appends a single element. What you want is append(contentsOf newElements: C).

但是你有 将[MyClass]数组转换显式转换为[MyProtocol]:

But you have to convert the [MyClass] array to [MyProtocol] explicitly:

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

在Swift中使用协议时进行类型转换,这个 将每个数组元素包装到一个容纳符合MyProtocol的内容"的盒子中,这不仅仅是重新解释 的数组.

As explained in Type conversion when using protocol in Swift, this wraps each array element into a box which holds "something that conforms to MyProtocol", it is not just a reinterpretation of the array.

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

The compiler does this automatically for a single value (that is why

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

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

compiles) but not for an array. In earlier Swift versions, you could not even cast an entire array with as [MyProtocol], you had to cast each individual element.