Skip to content

Making a protocol equatable

This morning I was playing with a couple of model objects, trying to find a way to make them conform to Equatable. That’s not a big deal, you might say… well, in this case I wanted to make the protocol those objects implement, not the actual objects, conform to Equatable, so things got a little tricky.

Let’s say this is where I started:

Now, I want everything that conforms to Drinkable to be Equatable. So this was my first attempt:

Nah-ha. “Extension of protocol ‘Drinkable’ cannot have an inheritance clause”

The solution? Turning things around little bit (would this qualify as “inverting the dependency”, haha-lol?) and enforce Equatable to respond to == when the type implementing Equatable is Drinkable. In other words…

Ta-dahhhhh!

Here is a playground, just for you: Protocol_Equatable.playground

2 Comments

  1. christophe christophe

    Hi Cesar !
    I’m in no way a Swift expert, but either there is a huge thing I can’t even see or the extension actually does not add anything.
    With the extension commented out the Playground’s results are identical.

    Moreover, Beer still does not conform to Equatable.
    ‘func == (lhs: Drinkable, rhs: Drinkable)’ just provides the ability to ‘compare’ (with == operator) two Drinkable but it does not make the Drinkable-conforming types Equatable.

    func takesAnEquatable(param: T) {
    print(param)
    }
    takesAnEquatable(guiness) // error: cannot invoke ‘takesAnEquatable’ with an argument list of type ‘(Beer)’

    As opposed to a type that does conform to Equatable:
    struct Water: Drinkable, Equatable {
    let name: String
    let alcohol: Float
    }
    func == (lhs: Water, rhs: Water) -> Bool { // Without that Water does not conform to Equatable
    return lhs.name == rhs.name && lhs.alcohol == rhs.alcohol
    }
    takesAnEquatable(evian) // prints: Water(name: “Evian”, alcohol: 0.0)

    ‘func == (lhs: Drinkable, rhs: Drinkable)’ just provides the ability to ‘compare’ two Drinkable, even with different types, regardless their Equatable-conforming.
    let evian = Water(name: “Evian”, alcohol: 0)
    print(evian == guiness) // false

    Equatable is about comparing two instances of the same type: func ==(_ lhs: Self, _ rhs: Self) -> Bool

  2. Christian Gossain Christian Gossain

    Dude! This is amazing! Worked like a charm for me on Swift 3.0.

Leave a Reply

Your email address will not be published. Required fields are marked *