0

I have a hierarchy of 2 Swift classes and need them to implement Comparable:

class Thing : Comparable {
    var name = "Thing"
    init(name : String){
        self.name = name
    }
}

class Thingy: Thing {
    override init(name: String){
        super.init(name: "Thingy")

    }  
}
func ==(lhs: Thing, rhs:Thing)->Bool{
    return lhs.name == rhs.name
}

To comply with Comparable, I need to implement this function:

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

So far so good, but what happens if I need a specific < function for different subtypes, such as:

func <(lhs: SubThing, rhs: Thing) -> Bool{
        return lhs.name < rhs.name
    }

How am I supposed to do this? The compiler seems to ignore this last declaration.

Will it also work if the types are inverted?

lhs: SubThing, rhs: Thing

instead of

lhs: Thing, rhs: SubThing

2 Answers 2

2

Generics to the rescue. Make your Equatable, Comparable functions generic. Constrain T to be a subclass of Thing.

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


let a = Thing(name: "alpha")
let b = Thingy(name: "beta")

a == b // false
Sign up to request clarification or add additional context in comments.

Comments

1

Overriding the < operator should take the most specific match, so in your case

func <(lhs: Thing, rhs: Thing) -> Bool {
    print("Base");
    return lhs.name < rhs.name
}

func <(lhs: Subthing, rhs: Thing) -> Bool {
    print("Child");
    return lhs.name < rhs.name
}

Subthing(name: "a") < Thing(name: "b")

should print Child, however this doesn't happen.

Overloading using generics seem to work though:

func < <T1:Thing, T2: Thing>(lhs: T1, rhs: T2) -> Bool {
    print("Base");
    return lhs.name < rhs.name
}

func < <T1: Subthing, T2: Thing>(lhs: T1, rhs: T2) -> Bool {
    print("Child");
    return lhs.name < rhs.name
}

Subthing(name: "a") < Thing(name: "b")

correctly prints Child.

It seems that generic overloading has better type matching than the basic overload.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.