koen
koen

Reputation: 5729

Can Comparable protocol be generic?

Consider this struct:

struct Person : Comparable {
    let name: String
    let age: Int
}

extension Person {
    static func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.name < rhs.name
    }

    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.age == rhs.age && lhs.name == rhs.name
    }
}

Person structs now sort by name.

But what if I want to be able to sort by either name or age, is there a way to make the < func generic ?

Upvotes: 3

Views: 248

Answers (2)

Chris Eidhof
Chris Eidhof

Reputation: 1544

You cannot make a protocol generic. There are two ways to solve your problem:

You could create a wrapper struct which only contains a Person value, but sorts by a different combination of properties.

Alternatively, you could think of a way to compose methods that compare two things. We've done this in a Swift Talk episode: https://talk.objc.io/episodes/S01E19-from-runtime-programming-to-functions (if you don't want to watch the video, you can read the transcript).

Upvotes: 2

N Shumway
N Shumway

Reputation: 63

Try this:

struct Person : Comparable {
    let name: String
    let age: Int
    let compareByAge: Bool
}

extension Person {
    static func < (lhs: Person, rhs: Person) -> Bool {
        if compareByAge {
            return lhs.age < rhs.age
        }
        return lhs.name < rhs.name
}

static func == (lhs: Person, rhs: Person) -> Bool {
    if compareByAge {
        return lhs.age == rhs.age
    }
    return lhs.name == rhs.name
}

Upvotes: 1

Related Questions