Go 1.18 ジェネリックの反変型
Go 1.18 では、ジェネリック型を使用して、型引数に応じて異なる型を持つ関数を定義できます。特定の種類の分散である反変性を使用すると、入力と出力の型の間の明確に定義された関係を維持しながら、関数がより広範囲の入力の型を受け入れることができます。
Pipe Function
提供されている Pipe 関数は、値を変換する関数を構成することを目的としています。左側の関数の出力型が右側の関数の入力型と一致することが期待されます。ただし、次の例ではコンパイルに失敗します。
func Pipe[A, T1, T2 any](left func(A) T1, right func(T1) T2) func(A) T2 { return func(a A) T2 { return right(left(a)) } } func OpenFile(name string) *os.File { ... } func ReadAll(rdr io.Reader) []byte { ... } var OpenRead = Pipe(OpenFile, ReadAll)
io.Reader と互換性があるにもかかわらず、T1 が *os.File であると見なされるため、コンパイラはエラーを出します。
解決策はありますか?
残念ながら、Go には解決策がありません。 1.18 ジェネリックを使用して Pipe のシグネチャを変更し、目的の動作を有効にします。 Go は共変の結果型をサポートしていません。つまり、関数の出力型は入力型に基づいて変化することはできません。
バグですか?
の動作Go 1.18 はバグではありません。 Go ジェネリックの FAQ で説明されているように、これは仕様によるものです。
回避策
この制限に対処するには、Pipe 関数の修正バージョンを使用できますが、コンパイル時の型安全性が犠牲になります:
func Pipe[A, T1, T2, T3 any](left func(A) T1, right func(T2) T3) func(A) T3 { return func(a A) T3 { return right(any(left(a)).(T2)) } }
以上が反変性はパイプ関数における Go 1.18 のジェネリック型の互換性問題を解決できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。