Go ジェネリック: マップ キーの型制約
質問:
次の理由は次のとおりです。汎用リンク リストをマップとして使用すると、コードがコンパイルに失敗するkey?
type List[X any] interface { isList() } type Cons[X any] struct { Data X Next List[X] } func (Cons[X]) isList() {} func main() { x := Cons[int]{5, Nil[int]{}} m := map[List[int]]string{} m[x] = "Hi" fmt.Println(m[x]) fmt.Println(id(x)) }
答え:
Go 1.18 および 1.19 では、事前に宣言された比較可能な制約がマップ キーに必要であり、使用が厳密に比較可能な型に制限されます。実行時にパニックを起こさずに == と != の比較をサポートします。インターフェイスは、等価比較をサポートしていますが、無限の型セットがあるため比較可能なものを実装しません。
List[X] インターフェイス自体はマップ キーとして使用できますが、Cons[X] 構造体はマップ キーとして使用できます。 List[X] フィールドが含まれているため、比較可能なものは実装されていません。マップ キーとしての使用に適した型を識別するために使用できる、これより弱い制約はありません。
ただし、Go 1.20 (2023 年 2 月) では、この動作は修正されました。比較により実行時にパニックが発生する可能性がある場合でも、comparative は、言語仕様に従って比較可能なすべての型を受け入れるようになりました。これにより、コードは正常にコンパイルできます。
代替制約:
isList() メソッドを含む制約を使用する必要がある場合は、独自の制約を定義できます。次のような制約を追加します:
type List interface { comparable isList() bool }
次に、マップ キー構造体にインターフェイスを宣言する代わりにこの List インターフェイスを実装させます。フィールド。
以上がGo (1.20 以前) でジェネリック リンク リストをマップ キーとして使用できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。