将数组中的所有项复制到引用类型的新数组中的函数

A function that copies all items in an array into a new array for reference types

当我创建一个数组并向其中添加一些对象(引用类型)时:

let myArray = [UILabel(), UIButton(), UIView()]

我可以通过复制数组的所有项来创建数组的 副本:

let myCopiedArray = myArray.map{ [=11=].copy() }

当我修改 myCopiedArray 中的任何项目时,它不会对原始 myArray 产生任何影响。

由于 map(_:) 函数总是有点难以阅读,我想将此复制操作包装到一个单独的函数中,并使用更具表现力的名称:

extension Array where Element: AnyObject {
    /// Creates a new array that contains a copy of each of the receiver's items.   
    func newArrayByCopyingItems() -> Array {
        return map{ [=12=].copy() }
    }
}

这不起作用,编译器对我理解我做错了什么没有帮助:

Cannot convert value of type '(_) -> _' to expected argument type '(_) -> _'

有没有人可以给我更有帮助的建议? ;)

(我怀疑编译器无法以某种方式推断参数 [=18=] 的类型 AnyObject,尽管它在扩展声明中明确定义。)

AnyObject 没有为其声明的 copy() 方法。

我将解释我用来得出答案的步骤。也许这会有所帮助。

开始于:let copiedArray = myArray.map { [=15=].copy() }

我首先寻找一个声明了 copy() 方法的协议,但没有找到。我在该方法中发现的最通用的 class 是 NSObject,所以看起来我必须使用它。然后我通过单击选项查看 copiedArray 的类型。我发现它是一个[Any]。所以这意味着我最终得到:

extension Array where Element: NSObject {
    func newArrayByCopyingItems() -> [Any] {
        return self.map { [=10=].copy() }
    }
}

不是很愉快,但就是这样。我可以通过创建自己的协议来使其更有用。这样做的好处是我可以维护复制数组的类型。缺点是我必须确保我想使用它的所有类型都符合扩展名...

使用下面的代码,我现在可以做到:

let myArray = [UILabel(), UIButton(), UIView()]
let myCopiedArray = myArray.newArrayByCopyingItems()

并且 myCopiedArray 将是一个 UIView 数组,而我无需转换它们。

protocol Copying {
    associatedtype Copied
    func makeCopy() -> Copied
}

extension Array where Element: Copying, Element.Copied == Element {
    func newArrayByCopyingItems() -> [Element] {
        return self.map { [=12=].makeCopy() }
    }
}

extension UIView: Copying {
    func makeCopy() -> UIView {
        return self.copy() as! Copied
    }
}