代码之家  ›  专栏  ›  技术社区  ›  Teetz

深度复制数组,其中元素是自定义类的可选元素

  •  2
  • Teetz  · 技术社区  · 7 年前

    正如标题所说,我正在尝试深度复制一个数组,该数组保存自定义类的可选对象。

    对于自定义类对象的深层副本,我实现了以下协议:

    protocol Copyable {
        init(instance: Self)
    }
    
    extension Copyable {
        func copy() -> Self {
            return Self.init(instance: self)
        }
    }
    

    Array 元素所在位置 Copyable ,它看起来像这样并且正在工作:

    extension Array where Element: Copyable {
        func clone() -> Array {
            var copiedArray = Array<Element>()
            for element in self {
                copiedArray.append(element.copy())
            }
            return copiedArray
        }
    }
    

    假设我有两个自定义类。第一个已经符合 可复制 看起来像这样:

    class MySimpleObject: Copyable {
    
        let myString: String
    
        init() {
            self.myString = ""
        }
    
        required init(instance: MySimpleObject) {
            self.myString = instance.myString
        }
    }
    

    现在我的第二个自定义类包含两个数组 MySimpleObject 我的简单对象 是非可选的,1中的元素 是可选的。这堂课看起来是这样的:

    class MyObject {
    
        var myArray = [MySimpleObject]()
        var myArrayWithOptionals = [MySimpleObject?]()
    }
    

    现在我想要 MyObject 可复制 这是让我困惑的部分。首先,我尝试了这样做(但这给了我一个错误,如注释中所示:

    class MyObject: Copyable {
    
        var myArray = [MySimpleObject]()
        var myArrayWithOptionals = [MySimpleObject?]()
    
        required init(instance: MyObject) {
            self.myArray = instance.myArray.clone()
            self.myArrayWithOptionals = instance.myArrayWithOptionals.clone()       // Type 'MySimpleObject?' does not conform to protocol 'Copyable'
        }
    }
    

    这个错误对我来说是有道理的。自从 MySimpleObject? 我的简单对象 .

    我的第二个尝试是编写数组的另一个扩展,但我不确定如何以正确的方式执行此操作:

    extension Array where Element == Optional<Copyable> {
        func cloneOptional() -> Array {
            var copiedArray = Array<Element>()
            for element in self {
                copiedArray.append(element?.copy())
            }
            return copiedArray
        }
    }
    

    肌体 看起来是这样的:但是我也得到了一个错误(再次显示在注释中)

    class MyObject: Copyable {
    
        var myArray = [MySimpleObject]()
        var myArrayWithOptionals = [MySimpleObject?]()
    
        required init(instance: MyObject) {
            self.myArray = instance.myArray.clone()
            self.myArrayWithOptionals = instance.myArrayWithOptionals.cloneOptional()   // '[MySimpleObject?]' is not convertible to 'Array<Optional<Copyable>>'
        }
    }
    

    有人能告诉我需要的方向吗?我们将如何以正确的方式实现这一点?

    如果你需要更多的信息,请在评论中告诉我。

    谨致问候,

    蒂茨

    1 回复  |  直到 7 年前
        1
  •  2
  •   Sandeep    7 年前

    对于可选元素的数组扩展,似乎有一点不正确的假设。你在打电话 copy 在您尚未声明的可选项上。只要确保 Optional 也符合 Copyable clone 在可选数组上。

    extension Optional: Copyable where Wrapped: Copyable {
        init(instance: Optional<Wrapped>) {
            if let instance = instance {
                self = Optional(instance.copy())
            } else {
                self = nil
            }
        }
    }
    

    总之,你的代码看起来像这样,

    protocol Copyable {
        init(instance: Self)
    }
    
    extension Copyable {
        func copy() -> Self {
            return Self.init(instance: self)
        }
    }
    
    extension Optional: Copyable where Wrapped: Copyable {
        init(instance: Optional<Wrapped>) {
            if let instance = instance {
                self = Optional(instance.copy())
            } else {
                self = nil
            }
        }
    }
    
    extension Array where Element: Copyable {
        func clone() -> [Element] {
            var copiedArray = [Element]()
            for element in self {
                copiedArray.append(element.copy())
            }
            return copiedArray
        }
    }
    
    class MySimpleObject: Copyable {
    
        let myString: String
    
        init() {
            self.myString = ""
        }
    
        required init(instance: MySimpleObject) {
            self.myString = instance.myString
        }
    }
    
    class MyObject: Copyable {
    
        var myArray = [MySimpleObject]()
        var myArrayWithOptionals = [MySimpleObject?]()
    
        required init(instance: MyObject) {
            self.myArray = instance.myArray.clone()
            self.myArrayWithOptionals = instance.myArrayWithOptionals.clone()
        }
    }