How do I implement Swift's Comparable protocol?

前端 未结 3 1851
轮回少年
轮回少年 2020-12-28 13:45

How do I use the Comparable protocol in Swift? In the declaration it says I\'d have to implement the three operations <, <= and >=. I put all those in the class but it

相关标签:
3条回答
  • 2020-12-28 14:28

    Here is an update of Kametrixom's answer for Swift 3:

    class Person : Comparable {
    
        let name : String
    
        init(name : String) {
            self.name = name
        }    
    
        static func < (lhs: Person, rhs: Person) -> Bool {
            return lhs.name < rhs.name
        }
    
        static func == (lhs: Person, rhs: Person) -> Bool {
            return lhs.name == rhs.name
        }
    }
    

    Instances of the Person class can then be compared with the relational operators as follows:

    let paul = Person(name: "Paul")
    let otherPaul = Person(name: "Paul")
    let ben = Person(name: "Ben")
    
    print(paul > otherPaul)  // false
    print(paul <= ben)       // false
    print(paul == otherPaul) // true
    
    0 讨论(0)
  • 2020-12-28 14:33

    The Comparable protocol extends the Equatable protocol -> implement both of them

    In Apple's Reference is an example from Apple (within the Comparable protocol reference) you can see how you should do it: Don't put the operation implementations within the class, but rather on the outside/global scope. Also you only have to implement the < operator from Comparable protocol and == from Equatable protocol.

    Correct example:

    class Person : Comparable {
        let name : String
    
        init(name : String) {
            self.name = name
        }
    }
    
    func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.name < rhs.name
    }
    
    func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name
    }
    
    let paul = Person(name: "Paul")
    let otherPaul = Person(name: "Paul")
    let ben = Person(name: "Ben")
    
    paul > otherPaul  // false
    paul <= ben       // false
    paul == otherPaul // true
    
    0 讨论(0)
  • 2020-12-28 14:39

    To implement Swift's Comparable protocol, you need to conform to the Equatable protocol first by implementing static func == (lhs: Self, rhs: Self) -> Bool, then implementing the only required function static func < (lhs: Self, rhs: Self) -> Bool for Comparable.

    Instead of declaring global operator overloads, you should instead implement the protocol conforming methods within the struct/class itself. Although global operator overloads satisfy the protocol conformance, it's bad practice to declare them that way instead of the intended static methods on the struct/class.

    If you look at the documentation example, you will see that the same is shown as sample code.

    I would instead write the following:

    class Person: Comparable {
        let name: String
    
        init(name: String) {
            self.name = name
        }
    
        static func < (lhs: Person, rhs: Person) -> Bool {
            return lhs.name < rhs.name
        }
    
        static func == (lhs: Person, rhs: Person) -> Bool {
            return lhs.name == rhs.name
        }
    }
    

    or even separate out the protocol conformance out of the class declaration like so:

    class Person {
        let name: String
    
        init(name: String) {
            self.name = name
        }
    }
    
    extension Person: Comparable {
        static func < (lhs: Person, rhs: Person) -> Bool {
            return lhs.name < rhs.name
        }
    
        static func == (lhs: Person, rhs: Person) -> Bool {
            return lhs.name == rhs.name
        }
    }
    

    which would probably be closer to production level code.

    0 讨论(0)
提交回复
热议问题