反変性はパイプ関数における Go 1.18 のジェネリック型の互換性問題を解決できますか?

Linda Hamilton
リリース: 2024-11-24 07:47:11
オリジナル
327 人が閲覧しました

Can Contravariance Solve Go 1.18's Generic Type Compatibility Issue in the Pipe Function?

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 サイトの他の関連記事を参照してください。

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