Craig Otis
Craig Otis

Reputation: 32054

Providing minimum implementations for overloaded comparison operators in Swift

I was pondering this morning how to properly implement the comparison operators in Swift. I have a class (a very lightweight date class) for which I have overloaded the equality operator:

func == (lhs: SimpleDate, rhs: SimpleDate) -> Bool {
    if (lhs.day != rhs.day) {
        return false
    }
    if (lhs.month != rhs.month) {
        return false
    }
    if (lhs.year != rhs.year) {
        return false
    }
    return true
}

But I would now also like to be able to use >, <, >=, and <=. When it comes to providing this functionality, is it a requirement to write all 4 functions?

It follows that for >= you could build on the already-written combination of == || >, but I was wondering if there was any way for this functionality to be automatically determined by Swift if it sees that == and > have both been implemented.

ie. is there a way to, rather than write these 5 globally-scoped functions in my class, override a special function/operator that allows me to return an NSComparisonResult or similar, and let Swift automatically overload all these operators for me?

Upvotes: 1

Views: 160

Answers (1)

Martin R
Martin R

Reputation: 539795

The answer is given in the "Swift Standard Library Reference":

Equatable

The Equatable protocol makes it possible to determine whether two values of the same type are considered to be equal.

There is one required operator overload defined in the protocol: ==.

Comparable

The Comparable protocol makes it possible to compare two values of the same type.

There is one required operator overload defined in the protocol (<), as well as one defined in the inherited Equatable protocol (==). By adopting the Comparable protocol and adding an operator overload for <, you automatically gain the ability to use >, <=, and >=.

So it is sufficient that your class conforms to Comparable, and the == and < operators are implemented:

class SimpleDate : Comparable {
    // ...
}

func == (lhs: SimpleDate, rhs: SimpleDate) -> Bool {
    // ...
}

func < (lhs: SimpleDate, rhs: SimpleDate) -> Bool {
    // ...
}

The remaining comparison operators !=, >, <= and >= are then provided by generic library methods.

Upvotes: 4

Related Questions