A purpose for Equatable and Hashable in Swift
There is a lot written on the subject of object equality and object hashes covering it in depth, but I wanted to summarise it and to frame it in the context of Swift. This article is not focused on how to implement these protocols, but more focused on why you would want to implement them.
Equatable expresses under what conditions type instances are considered to be equivalent (or equal) through the lens of a certain business logic. There is no correct or incorrect way of implementing equality, it all depends on how you want to define it in your code. For example, when implementing equality for a data model type, you can take into consideration all properties or only a subset of them.
There are two reasons why you may want to implement
- you can easily compare type instances using the
!=operators throughout your code
- some collections like
Arrayprovide searching functions like
containswhich can take an element directly as a parameter instead of closure as they would otherwise do
Now if you want to store your items in collections such as
Dictionarys, it’s a requirement that you implement
Hashable. This is purely for performance optimization reasons. From a logical point of view, equality alone is enough to have items organised in sets. However, because the underlying implementations of
Dictionary use hash tables in order to make lookups faster, one must conform to
Sets will admit two elements that have the same
hashValue, provided that the elements are not equal as defined when conforming to the
Equatable protocol. However, this strips away the performance gain of hash lookups.
There is a strong connection between the two protocols in Swift:
- they are both useful when dealing with elements as part of collections
- they both refer to the concept of equality through the lens of a domain specific logic
- one defines the equality concept more thoroughly while the other optimizes it for use in hash tables
For more in depth reading: