How To Get Equatable And Hashable For Free

Swift 4.1 is available with Xcode 9.3 and brings a nice gift. The compiler can now automatically generate the code to make your types Equatable or Hashable. This only applies to structs and enums (not classes) and there are conditions but this can still save you from a lot of boring boilerplate code.

Automatic Synthesis Of Equatable

For a recap of how and when to make your types equatable see this earlier post. In that example I had a struct representing a country with two String properties and a Bool:

struct Country {
  let name: String
  let capital: String
  var visited: Bool
}

To make this type Equatable meant adopting the protocol and implementing the static == operator for the type. I did that in an extension:

extension Country: Equatable {
  static func == (lhs: Country, rhs: Country) -> Bool {
    return lhs.name == rhs.name &&
    lhs.capital == rhs.capital &&
    lhs.visited == rhs.visited
  }
}

Now with Swift 4.1 you can remove the boilerplate extension code. You only need to tell the compiler that you want this type to be Equatable by declaring conformance to the protocol:

struct Country: Equatable {
  let name: String
  let capital: String
  var visited: Bool
}

That’s it! The compiler will do the rest.

let france = Country(name: "France", capital: "Paris", visited: true)
let spain = Country(name: "Spain", capital: "Madrid", visited: true)
if france == spain { ... } // false

Automatic Synthesis Of Hashable

For a recap of how and when to make your types hashable see this earlier post. A common reason is to store them in a Set or Dictionary.

To manually make my Country type hashable I needed to implement the hashValue property:

extension Country: Hashable {
  var hashValue: Int {
  return name.hashValue ^ capital.hashValue ^ visited.hashValue
  }
}

Starting with Swift 4.1 we can delete this boilerplate and let the compiler do the work. Automated synthesis of Hashable works much like Equatable. Declare conformance in the type declaration and your type gets a hashValue:

struct Country: Hashable {
  let name: String
  let capital: String
  var visited: Bool
}

let uk = Country(name: "United Kingdom", capital: "London", visited: true)
visited[uk] = 5

Since Hashable inherits from Equatable you do not need to include the Equatable declaration in this case.

Some Conditions Apply

Always read the small print…

Further Reading

Never miss a post

iOS Size Classes Cheat Sheet

Subscribe and also get my free iOS Size Classes Cheat Sheet

Success! Now check your email to confirm your subscription and download your free guide to iOS Size Classes.

There was an error submitting your subscription. Please try again.

Unsubscribe at any time. See Privacy Policy
No time to watch WWDC videos?

Sign up to get my iOS posts and news direct to your inbox and also get my free iOS Size Classes Cheat Sheet

OK! Check your inbox (or spam folder) for an email to confirm your details and download your free guide to iOS Size Classes.

There was an error submitting your subscription. Please try again.

Unsubscribe at any time. See Privacy Policy
Archives Categories