Array of protocol type

前端 未结 3 1401
感动是毒
感动是毒 2021-02-15 11:24

I have checked all answers about this problem on stackoverflow, but still can not figure out how to fix this. My model looks like this

protocol Commandable: Eq         


        
3条回答
  •  感情败类
    2021-02-15 11:44

    I think it can be easily done by introduction of your own CustomEquatable protocol.

    protocol Commandable: CustomEquatable {
        var condition: String {get}
    }
    
    protocol CustomEquatable {
        func isEqual(to: CustomEquatable) -> Bool
    }
    

    Then, you objects have to conform to this protocol and additionally it should conform Equitable as well.

    struct MoveCommand: Commandable, Equatable {
        let movingVector: CGRect
        let condition: String
    
        func isEqual(to: CustomEquatable) -> Bool {
            guard let rhs = to as? MoveCommand else { return false }
    
            return movingVector == rhs.movingVector && condition == rhs.condition
        }
    }
    
    struct RotateCommand: Commandable, Equatable {
        let side: CGFloat
        let condition: String
    
        func isEqual(to: CustomEquatable) -> Bool {
            guard let rhs = to as? RotateCommand else { return false }
    
            return side == rhs.side && condition == rhs.condition
        }
    }
    

    All you need to do now is connect your CustomEquatable protocol to Swift Equatable through generic extension:

    extension Equatable where Self: CustomEquatable {
    
        static func ==(lhs: Self, rhs: Self) -> Bool {
            return lhs.isEqual(to: rhs)
        }
    }
    

    It's not a perfect solution, but now, you can store your objects in a array of protocol objects and use == operator with your objects as well. For example(I simplified objects a little bit):

    let move = MoveCommand(movingVector: .zero, condition: "some")
    let rotate = RotateCommand(side: 0, condition: "some")
    
    var array = [Commandable]()
    array.append(move)
    array.append(rotate)  
    
    let equal = (move == MoveCommand(movingVector: .zero, condition: "some"))
    let unequal = (move == MoveCommand(movingVector: .zero, condition: "other"))
    let unequal = (move == rotate) // can't do this, compare different types
    

    PS. Using var on struct is not a good practice, especially for performance reasons.

提交回复
热议问题