24

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?

4
  • 3
    You could simply use the overflow operators (&+ and &*) to allow integer overflows in your hash calculation. developer.apple.com/library/prerelease/ios/documentation/swift/… Commented Jun 16, 2014 at 8:51
  • Good point. I need to finish reading the Swift book. ;) Commented Jun 16, 2014 at 8:57
  • 1
    You might want to edit your question. hashValue is not a func. Instead, it's a computed property. Commented Jun 25, 2014 at 1:01
  • Does this answer your question? How to Implement hash(into:) from hashValue in Swift? Commented Oct 1, 2020 at 19:45

1 Answer 1

27

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

Sign up to request clarification or add additional context in comments.

3 Comments

You might want to edit your answer. hashValue is not a func. Instead, it's a computed property.
does it make a difference which one I choose to be property1 or property2? suppose property1 goes from 0 to 2 while property2 goes from 0 to some big n...
This approach slowed my compilation time down by a factor of 10000. Xcode Version 8.0 (8A218a).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.