Go 1.18 以前では、マップ キーとして使用される型には、事前に宣言された比較可能な制約が必要です。この制約により、型が == 演算子と != 演算子をサポートし、これらの演算子が使用されたときにパニックが発生しないことが保証されます。
ただし、この制約は、マップ キーとして使用できる型に必ずしも適切であるとは限りません。たとえば、次のコードは汎用リンク リストを定義します。
type List[X any] interface { isList() } type Cons[X any] struct { Data X Next List[X] } func (Cons[X]) isList() {} type Nil[X any] struct{} func (Nil[X]) isList() {}
このコードは、Cons と Nil の 2 つの型で実装される List インターフェイスを定義します。 Cons 型は空ではないリストを表し、Nil 型は空のリストを表します。
次のコードは、List インターフェイスを使用してリストの文字列へのマップを作成します。
type List[X any] interface { isList() } func main() { x := Cons[int]{5, Nil[int]{}} m := map[List[int]]string{} m[x] = "Hi" // succeeds fmt.Println(m[x]) // prints "Hi" }
このコードは正常にコンパイルされ、実行されます。ただし、型 Cons のメソッドを使用しようとすると、コンパイラ エラーが発生します。
type List[X any] interface { isList() } func main() { x := Cons[int]{5, Nil[int]{}} fmt.Println(id(x)) // error: Cons[int] does not implement comparable }
このエラー メッセージは、型 Cons[int] が比較可能な制約を実装していないことを示します。これは、Cons 型に List[int] 型のフィールドがあり、List[int] インターフェイスが同等の制約を実装していないためです。
この問題に対する考えられる解決策の 1 つは、より弱い型制約を使用することです。たとえば、次の制約を使用できます:
type List[X any] interface { isList() Comparable() bool }
この制約により、比較可能な制約が実装されていない場合でも、Cons タイプをマップ キーとして使用できます。
同等の制約は、マップ キーの正しいキャッチオール制約です。 Go 仕様に従って比較可能なすべての型は、実行時に比較がパニックになる可能性がある場合でも、比較可能な制約を満たすことができます。コードは 1.20 で期待どおりにコンパイルされます。
これにより、仕様の比較可能な型と比較可能な型に関する以前の Go バージョンの不一致が最終的に修正されました。
以上がGo ジェネリックの「比較可能な」制約をマップ キーに対して緩和できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。