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中文網其他相關文章!