Make your custom types easier to use by ensuring that they conform to Swift protocols.
When using custom types to model data in your programs, you may frequently need to check whether two values are the same or different, or whether a particular value is included in a list of values. This capability, as well as the ability to store values in a set or use them as keys in a dictionary, are governed by two related standard library protocols,
You can compare instances of an equatable type by using the equal-to (
==) and not-equal-to (
An instance of a hashable type can reduce its value mathematically to a single integer, which is used internally by sets and dictionaries to make lookups consistently fast.
Many standard library types are both equatable and hashable, including strings, integers, floating-point values, Boolean values, and collections of equatable and hashable types. The
== comparison and the
contains(_:) method call in the following example depend on strings and integers being equatable:
Conforming to the
Hashable protocols is straightforward and makes it easier to use your own types in Swift. It's a good idea for all your custom model types to conform.
Conform Automatically to Equatable and Hashable
You can make many custom types equatable and hashable by simply declaring these protocol conformances in the same file as the type's original declaration. Add
Hashable to the list of adopted protocols when declaring the type, and the compiler automatically fills in the requirements for the two protocols:
Equatable conformance, you can use the equal-to operator (
==) or the not-equal-to operator (
!=) with any two instances of the
Hashable conformance means that you can store positions in a set and quickly check whether you've visited a position before, as shown in the following example:
In addition to simplifying your code, this automatic conformance reduces errors, because any new properties you add to your custom types are automatically included when hashing and testing for equality. A type is eligible for automatic conformance to
Hashable when it's a structure or an enumeration that meets these criteria:
For a structure, all its stored properties must conform to
For an enumeration, all its associated values must conform to
Hashable. (Enumerations without associated values have
Hashableconformance even without declaring adoption.)
Conform Manually to Equatable and Hashable
You need to manually implement
Hashable conformance for a type in these cases:
The type doesn't meet the criteria listed in the previous section.
You want to customize the type's conformance.
You want to extend a type declared in another file or module to conform.
Player type is a class, so it doesn't qualify for automatic synthesis of the
Hashable requirements. To make this class conform to the
Equatable protocol, declare conformance in an extension and implement the static
== operator method. Compare each significant property for equality in your
== method's implementation:
Player conform to the
Hashable protocol, declare conformance in another extension and implement the
hash(into:) method. In the
hash(into:) method, call the
combine(_:) method on the provided hasher with each significant property:
Use All Significant Properties for Equatable and Hashable
When implementing the
== method and the
hash(into:) method, use all the properties that affect whether two instances of your custom type are considered equal. In the implementations above, the
Player type uses
position in both methods.
If your type contains properties that don't affect whether two instances are considered equal, exclude those properties from comparison in the
== method and from hashing in
hash(into:). For example, a type might cache an expensive computed value so that it only needs to calculate it once. If you compare two instances of that type, whether or not the computed value has been cached shouldn't affect their equality, so the cached value should be excluded from comparison and hashing.
Customize NSObject Subclass Behavior
NSObject subclasses inherit conformance to the
Hashable protocols, with equality based on instance identity. If you need to customize this behavior, override the
is method and
hash property instead of the
== operator method and
As noted in the previous section, two instances that are considered equal must have the same hash value. If you override one of these declarations, you must also override the other to maintain that guarantee.