On project we are using classes for model's layer and because of that I have to write code like this:
// MARK: - Hashable
extension Player: Hashable {
static func == (lhs: Player, rhs: Player) -> Bool {
return lhs.hashValue == rhs.hashValue
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.name)
}
}
Can this boilerplate can be somehow avoided? Is it possible to implement that Equatable compare by .hashValue by default? Thanks.
This is wrong, and it would make no sense that the compiler synthesizes it automatically:
static func == (lhs: Player, rhs: Player) -> Bool {
return lhs.hashValue == rhs.hashValue
}
Identical objects must have the same hash value, but not the other way around: Distinct objects can have the same hash value.
Concretely, in your example: The name is a string and there are infinitely many different strings, but only 264 different hash values. So there must be two different strings with the same hash value.
If all stored properties are Hashable then the compiler can synthesize the conformance for you completely. For example
struct Player : Equatable, Hashable {
let name: String
var score: Int
}
Here two players are “identical” if they have the same name and the same score.
If there are non-hashable properties, or if you want to customize the concept of identity then you have to override == and hash(into) accordingly. The hash function should use the same properties which determine the identity in ==. For example
struct Player : Equatable, Hashable {
let name: String
var score: Int
static func == (lhs: Player, rhs: Player) -> Bool {
return lhs.name == rhs.name
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.name)
}
}
Now two players are “identical” if they have the same name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With