Swift 2 add protocol conformance to protocols

后端 未结 2 687
盖世英雄少女心
盖世英雄少女心 2021-02-01 18:53

Can I add protocol conformance to a protocol via a swift extension?

//Plain old protocol here
protocol MyData {
    var myDataID: Int { get }
}
<
相关标签:
2条回答
  • 2021-02-01 19:40

    As the error message says: an extension of a protocol cannot have an inheritance clause. Instead, you could make MyData protocol inherit from Equatable in the original declaration.

    protocol MyData: Equatable {
        var myDataID: Int { get }
    }
    

    You could then extend add an implementation of == for types that conform to MyData:

    func == <T: MyData>(lhs: T, rhs: T) -> Bool {
        return lhs.myDataID == rhs.myDataID
    }
    

    However, I would highly not recommend this! If you add more properties to conforming types, their properties won't be checked for equality. Take the example below:

    struct SomeData: MyData {
        var myDataID: Int
        var myOtherData: String
    }
    
    let b1 = SomeData(myDataID: 1, myOtherData: "String1")
    let b2 = SomeData(myDataID: 1, myOtherData: "String2")
    
    b1 == b2 // true, although `myOtherData` properties aren't equal.
    

    In the case above you'd need to override == for SomeData for the correct result, thus making the == that accepts MyData redundant.

    0 讨论(0)
  • 2021-02-01 19:53

    Does this playground do what you want? I made it based on what I understand from Protocol-Oriented Programming in Swift from WWDC 2015.

    import Foundation
    
    //Plain old protocol here
    
    func == (lhs: MyData, rhs: MyData) -> Bool {
        return lhs.myDataID == rhs.myDataID
    }
    
    func != (lhs: MyData, rhs: MyData) -> Bool {
        return lhs.myDataID != rhs.myDataID
    }
    
    protocol MyData {
        var myDataID: Int { get }
    }
    
    extension MyData where Self: Equatable {
    
    }
    
    
    struct BananaData: MyData {
        var myDataID: Int = 1
    }
    
    func checkEquatable(bananaOne: BananaData, bananaTwo: BananaData) {
        //This compiles, verifying that BananaData can be compared
        if bananaOne == bananaTwo {
            print("Same")
        }
        //But BananaData is not convertible to Equatable, which is what I want
        //I don't get the additional operations added to Equatable (!=)
        print(bananaOne.myDataID)
        print(bananaTwo.myDataID)
    
    
        if bananaOne != bananaTwo {
    
        }
    
        //Error
    
    
    }
    
    let b1 = BananaData(myDataID: 2)
    let b2 = BananaData(myDataID: 2)
    
    checkEquatable(b1, bananaTwo: b2)
    
    let c = b1 == b2  // Evaluates as true
    
    0 讨论(0)
提交回复
热议问题