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



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

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

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

let myCopiedArray = myArray.map{ $0.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{ $0.copy() }
    }
}

这不是工作,编译器也无助于我理解我做错了什么:

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

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

(我怀疑编译器无法以某种方式推断参数AnyObject的类型$0尽管它在扩展声明中显式定义。

AnyObject没有

为其声明copy()方法。

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

开头:let copiedArray = myArray.map { $0.copy() }

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

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

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

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

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

myCopiedArray将是一组 UIViews,而无需我投射它们。

protocol Copying {
    associatedtype Copied
    func makeCopy() -> Copied
}
extension Array where Element: Copying, Element.Copied == Element {
    func newArrayByCopyingItems() -> [Element] {
        return self.map { $0.makeCopy() }
    }
}
extension UIView: Copying {
    func makeCopy() -> UIView {
        return self.copy() as! Copied
    }
}

相关内容

  • 没有找到相关文章

最新更新