Go 1.18 では、タイプセーフなコードの作成を可能にするジェネリックが導入されました。ただし、反変型など、特定の動作は期待と異なる場合があります。
Go 1.18 の次の関数について考えてみましょう。
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)) } }
この関数は、 left の出力を右に入力します。ただし、次のように使用するとコンパイルに失敗します:
func OpenFile(name string) *os.File { ... } func ReadAll(rdr io.Reader) []byte { ... } var OpenRead = Pipe(OpenFile, ReadAll)
これは、コンパイラが T1 が *os.File であると判断するためです。これは、たとえ互換性があるとしても io.Reader と同一ではありません。
望ましい動作は、互換性のある型を入力として受け入れる関数と 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 ジェネリックで「Pipe」関数が互換性のある型でコンパイルに失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。