Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a good Hashable implementation in Swift

Tags:

swift

hash

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?

like image 477
orj Avatar asked Jun 16 '14 08:06

orj


People also ask

What does it mean to be hashable Swift?

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 { ... }

Is string hashable in Swift?

Many types in the standard library conform to Hashable : Strings, integers, floating-point and Boolean values, and even sets are hashable by default.

What is Hasher in Swift?

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.

Is Dictionary hashable in Swift?

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.


1 Answers

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

like image 139
orj Avatar answered Oct 22 '22 02:10

orj