ホームページ > バックエンド開発 > Golang > Go ジェネリックの「比較可能な」制約をマップ キーに対して緩和できますか?

Go ジェネリックの「比較可能な」制約をマップ キーに対して緩和できますか?

Susan Sarandon
リリース: 2024-12-18 12:38:22
オリジナル
659 人が閲覧しました

Can Go Generics' `comparable` Constraint Be Relaxed for Map Keys?

Go ジェネリック: マップ キーの型制約?

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 (2023 年 2 月)

同等の制約は、マップ キーの正しいキャッチオール制約です。 Go 仕様に従って比較可能なすべての型は、実行時に比較がパニックになる可能性がある場合でも、比較可能な制約を満たすことができます。コードは 1.20 で期待どおりにコンパイルされます。

これにより、仕様の比較可能な型と比較可能な型に関する以前の Go バージョンの不一致が最終的に修正されました。

以上がGo ジェネリックの「比較可能な」制約をマップ キーに対して緩和できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート