The reason you should think twice about Equatable is because in many cases this just doesn't make sense. Consider this example:
protocol Pet: Equatable { var age: Int { get } } extension Pet { static func == (lhs: Pet, rhs: Pet) -> Bool { return lhs.age == rhs.age } } struct Dog: Pet { let age: Int let favoriteFood: String } struct Cat: Pet { let age: Int let favoriteLitter: String } let rover: Pet = Dog(age: "1", favoriteFood: "Pizza") let simba: Pet = Cat(age: "1", favoriteLitter: "Purina") if rover == simba { print("Should this be true??") }
You refer to type checking in the implementation == , but the problem is that you have no information that either of them is not Pet , and you do not know everything that Pet can be (maybe you will add Bird and Rabbit later ) If you really need it, another approach might be to model how languages ββlike C # implement equality by doing something like:
protocol IsEqual { func isEqualTo(_ object: Any) -> Bool } protocol Pet: IsEqual { var age: Int { get } } struct Dog: Pet { let age: Int let favoriteFood: String func isEqualTo(_ object: Any) -> Bool { guard let otherDog = object as? Dog else { return false } return age == otherDog.age && favoriteFood == otherDog.favoriteFood } } struct Cat: Pet { let age: Int let favoriteLitter: String func isEqualTo(_ object: Any) -> Bool { guard let otherCat = object as? Cat else { return false } return age == otherCat.age && favoriteLitter == otherCat.favoriteLitter } } let rover: Pet = Dog(age: "1", favoriteFood: "Pizza") let simba: Pet = Cat(age: "1", favoriteLitter: "Purina") if !rover.isEqualTo(simba) { print("That more like it.") }
At what point, if you really wanted to, you could implement == without implementing Equatable :
static func == (lhs: IsEqual, rhs: IsEqual) -> Bool { return lhs.isEqualTo(rhs) }
One thing you would have to observe in this case is inheritance. Since you can flush the inheriting type and delete information that may make isEqualTo not logical.
The best thing is to only implement equality for the class / structure itself and use a different type checking mechanism.
Scott h
source share