首頁 > 後端開發 > Golang > 逆變可以解決 Go 1.18 的 Pipe 函數中的泛型型別相容性問題嗎?

逆變可以解決 Go 1.18 的 Pipe 函數中的泛型型別相容性問題嗎?

Linda Hamilton
發布: 2024-11-24 07:47:11
原創
390 人瀏覽過

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

Go 1.18 泛型中的逆變類型

在Go 1.18 中,泛型類型允許定義類型隨類型參數而變化的函數。逆變是一種特定類型的方差,它允許函數接受更廣泛的輸入類型,同時保持輸入和輸出類型之間定義良好的關係。

管道函數

提供的 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)
登入後複製

編譯器會抱怨,因為 T1 被認為是 *os.File,即使它與 io.Reader 相容。

有解決方法嗎?

不幸的是,Go 1.18 沒有辦法泛型修改 Pipe 的簽名以啟用所需的行為。 Go 不支援協變結果類型,這表示函數的輸出類型不能根據輸入類型而變化。

這是一個 Bug 嗎?

中的行為Go 1.18 不是一個 bug。這是設計使然,正如 Go 泛型常見問題解答中所解釋的那樣。

解決方法

要解決此限制,可以使用 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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板