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