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?

orj
  • 13,234
  • 14
  • 63
  • 73
  • 3
    You could simply use the overflow operators (&+ and &*) to allow integer overflows in your hash calculation. https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/AdvancedOperators.html – Fabian Kreiser Jun 16 '14 at 08:51
  • Good point. I need to finish reading the Swift book. ;) – orj Jun 16 '14 at 08:57
  • 1
    You might want to edit your question. hashValue is not a func. Instead, it's a computed property. – pohl Jun 25 '14 at 01:01
  • Does this answer your question? [How to Implement hash(into:) from hashValue in Swift?](https://stackoverflow.com/questions/55687214/how-to-implement-hashinto-from-hashvalue-in-swift) – Rivera Oct 01 '20 at 19:45

1 Answers1

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

orj
  • 13,234
  • 14
  • 63
  • 73
  • 8
    You might want to edit your answer. hashValue is not a func. Instead, it's a computed property. – pohl Jun 25 '14 at 01:01
  • 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... – kfmfe04 Jan 15 '15 at 07:28
  • 1
    This approach slowed my compilation time down by a factor of 10000. Xcode Version 8.0 (8A218a). –  Oct 28 '16 at 11:55