Implementing copy() in Swift

前端 未结 10 1478
难免孤独
难免孤独 2020-11-27 15:31

I want to be able to copy a custom class in Swift. So far, so good. In Objective-C I just had to implement the NSCopying protocol, which means implementing

10条回答
  •  时光说笑
    2020-11-27 16:13

    IMO, the simplest way to achieve this is :

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

    Implemented in a struct as :

    struct Struct : Copyable
    {
      var value: String
    
      init(value: String)
      {
        self.value = value
      }
    
      init(other: Struct)
      {
        value = other.value
      }
    }
    

    And, in a class, as :

    class Shape : Copyable
    {
      var color: NSColor
    
      init(color: NSColor)
      {
        self.color = color
      }
    
      required init(other: Shape)
      {
        color = other.color
      }
    }
    

    And in subclasses of such a base class as :

    class Circle : Shape
    {
      var radius: Double = 0.0
    
      init(color: NSColor, radius: Double)
      {
        super.init(color: color)
    
        self.radius = radius
      }
    
      required init(other: Shape)
      {
        super.init(other: other)
    
        if let other = other as? Circle
        {
          radius = other.radius
        }
      }
    }
    
    
    class Square : Shape
    {
      var side: Double = 0.0
    
      init(color: NSColor, side: Double)
      {
        super.init(color: color)
    
        self.side = side
      }
    
      required init(other: Shape)
      {
        super.init(other: other)
    
        if let other = other as? Square
        {
          side = other.side
        }
      }
    }
    

    If you want to be able to copy an array of Copyable types :

    extension Array where Element : Copyable
    {
      func copy() -> Array
      {
        return self.map { $0.copy() }
      }
    }
    

    Which then allows you to do simple code like :

    {
      let shapes = [Circle(color: .red, radius: 5.0), Square(color: .blue, side: 5.0)]
    
      let copies = shapes.copy()
    }
    

提交回复
热议问题