新機能
hash/maphashに、comparable型向けのHasher実装を簡単に得られるComparableHasher型が追加された
hash/maphash
この項目の注釈は AI により生成されており、誤りを含む場合があります。
使用例のコンパイル検証: 検証済み
概要
hash/maphashパッケージにComparableHasher[T]型が追加された。これはHasher[T]インターフェースの実装であり、Equalメソッドが==と一致するように定義されている。comparable型をBloom filterなど独自のハッシュベースのデータ構造で扱いたい場合に、Hash/Equalメソッドを自前で書かずに済む。
使用例
Before
package main
import "hash/maphash"
// comparable型向けのHasherを使うには、Hash/Equalメソッドを
// 自前で実装する必要があった。
type stringHasher struct{}
func (stringHasher) Hash(h *maphash.Hash, s string) {
maphash.WriteComparable(h, s)
}
func (stringHasher) Equal(x, y string) bool { return x == y }
func main() {
var hasher maphash.Hasher[string] = stringHasher{}
_ = hasher
}
After
package main
import "hash/maphash"
func main() {
// comparable型であれば ComparableHasher をそのまま使える。
var hasher maphash.Hasher[string] = maphash.ComparableHasher[string]{}
_ = hasher
}
移行時の注意
追加のみの変更であり、既存コードへの影響はない。ただしComparableHasher[T]は型パラメータTがcomparable制約を満たすことのみを要求しており、ComparableHasher[any]のような具体化自体はコンパイルが通ってしまう。この場合、Hash/Equalに非comparableな値を渡すと実行時パニックになるため、実際に渡す値がcomparableであることは呼び出し側の責任で保証する必要がある。
実装解説
ComparableHasher[T]は空のstructで、HashメソッドはWriteComparableを呼ぶだけ、Equalメソッドは単純にx == yを返すだけの実装になっている(hasher.go;l=138)。
構造体には_ [0]func(T)という長さ0のフィールドが定義されている(hasher.go;l=135)。関数型フィールドを持たせることでComparableHasher[T]自体を==で比較できないようにし、かつComparableHasher[X]とComparableHasher[Y]の間の変換もできないようにしている。