There is an overload of Hasher.combine(bits:)
that takes an UnsafeRawBufferPointer
. Do you think we need to provide more ways to hash bulk data?
Hash memoization and custom hash functions are still possible in the hash(into:)
world, although they will incur the cost of feeding a single word to Hasher
. (This is similar to how Swift 4.1's Set
and Dictionary
unconditionally postprocess hash values with _mixInt
, it's just more explicit.)
class Foo: Hashable {
// ...
var _cachedHash: Int? = nil
func hash(into hasher: inout Hasher) {
if let hash = _cachedHash {
hasher.combine(bits: hash)
return
}
var hash = 0
// Calculate hash however you like
_cachedHash = hash
hasher.combine(bits: hash)
}
}
I think we should be careful not to overgeneralize Hashable
; I consider it more as a support protocol for Set
and Dictionary
, rather than something that should cover all possible forms of hashing.
For example, custom seed values makes it possible to use Hashable
types in e.g. some forms of Bloom filters. This is a nice bonus, but it is not why we added this feature -- the proposal adds supports for custom seed values because this turned out to be a requirement for Set
/Dictionary
. These collections have no need for an uncombine
operation, so Hasher
doesn't provide it -- rolling hashes would needlessly restrict the pool of hash functions Hasher
could implement.
For specialized/generalized hashing requirements, I think it is best to define separate protocol(s).