Swift Equatable on a protocol

前端 未结 10 2121
时光说笑
时光说笑 2021-01-30 12:42

I don\'t think this can be done but I\'ll ask anyway. I have a protocol:

protocol X {}

And a class:

class Y:X {}
10条回答
  •  一向
    一向 (楼主)
    2021-01-30 13:15

    Determining equality across conformances to a Swift protocol is possible without type erasure if:

    • you are willing to forgo the operator syntax (i.e. call isEqual(to:) instead of ==)
    • you control the protocol (so you can add an isEqual(to:) func to it)
    import XCTest
    
    protocol Shape {
        func isEqual (to: Shape) -> Bool
    }
    
    extension Shape where Self : Equatable {
        func isEqual (to: Shape) -> Bool {
            return (to as? Self).flatMap({ $0 == self }) ?? false
        }
    }
    
    struct Circle : Shape, Equatable {
        let radius: Double
    }
    
    struct Square : Shape, Equatable {
        let edge: Double
    }
    
    class ProtocolConformanceEquality: XCTestCase {
    
        func test() {
            // Does the right thing for same type
            XCTAssertTrue(Circle(radius: 1).isEqual(to: Circle(radius: 1)))
            XCTAssertFalse(Circle(radius: 1).isEqual(to: Circle(radius: 2)))
    
            // Does the right thing for different types
            XCTAssertFalse(Square(edge: 1).isEqual(to: Circle(radius: 1)))
        }
    
    }
    

    Any conformances don't conform to Equatable will need to implement isEqual(to:) themselves

提交回复
热议问题