MiddleCodeCommonNot answered yet
When does Swift synthesize Equatable/Hashable, and when must you write ==/hash(into:) by hand?
You have a User model with an id, a name, and a lastSeen date. Two users are the same when their id matches, regardless of the other fields.
Requirements:
- Make
Userconform toEquatableandHashable. - Base both equality and hashing on
idonly. - Do not rely on compiler synthesis, which would compare every stored property.
struct User {
let id: UUID
var name: String
var lastSeen: Date
// add the conformance here
}
Write the == and hash(into:) implementations.
Swift synthesizes Equatable/Hashable when every stored property conforms and you declare it in the type's file. Write them by hand when equality should ignore fields — compare only id in == and feed just id to hash(into:).
- ✗Thinking synthesis still works when a stored property doesn't conform
- ✗Feeding different fields to
==andhash(into:), breaking the hash contract - ✗Believing you must always write both by hand
- →Why must equal values always produce equal hashes?
- →Where must the conformance be declared for synthesis to kick in?
Equality and hashing are keyed on id alone:
extension User: Equatable, Hashable {
static func == (lhs: User, rhs: User) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
Compiler synthesis would compare and hash name and lastSeen too, so the same user with a newer lastSeen would count as different. Feeding only id to both methods keeps the core contract intact: equal values must produce equal hashes, and here both derive from id alone.