In Objective-C (and other languages) a relatively good default implementation of - (NSUInteger)hash
might be:
- (NSUInteger)hash {
return 31u * [self.property1 hash] + [self.property2 hash];
}
Assuming both property1
and property2
return good values for hash
.
This doesn't work in Swift's equivalent var hashValue: Int
method defined on its Hashable
protocol.
The equivalent Swift code is likely to overflow and this a runtime error in Swift.
var hashValue: Int {
return 31 * property1.hashValue + property2.hashValue // overflow-tastic
}
So my question is, what is the best technique for generating hash values (implementing Hashable) in Swift? Should I just use XOR? Though my understanding is that XOR is not ideal for creating uniform hash distributions. Perhaps something more exotic?
In Swift, a Hashable is a protocol that provides a hashValue to our object. The hashValue is used to compare two instances. To use the hashValue , we first have to conform (associate) the type (struct, class, etc) to Hashable property. For example, struct Employee: Hashable { ... }
Many types in the standard library conform to Hashable : Strings, integers, floating-point and Boolean values, and even sets are hashable by default.
Within the execution of a Swift program, Hasher guarantees that finalizing it will always produce the same hash value as long as it is fed the exact same sequence of bytes.
Any type that conforms to the Hashable protocol can be used as a dictionary's Key type, including all of Swift's basic types. You can use your own custom types as dictionary keys by making them conform to the Hashable protocol.
As suggested by Fabian Kreiser one can use the overflow operators to make the hashValue method as follows:
var hashValue: Int {
return (31 &* property1.hashValue) &+ property2.hashValue
}
The value still overflows, but at least it doesn't crash
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