Golang 1.18 泛型中的協變:了解其局限性
Golang 1.18 泛型的引入帶來了許多進步,但仍然存在某些局限性,包括缺乏完整的協方差支持。
理解問題
考慮一個場景,您想要定義一個名為Pipe 的通用函數,它接受兩個函數:
目標是建立一個函數,將左邊的輸出作為右側的輸入執行。但是,以下實作在某些情況下無法編譯:
出現此問題是因為 Golang 泛型不完全支援協方差。協變意味著類型參數可以用子類型替換而不違反約定。在這種情況下,T1 不允許子類型,而 io.ReadCloser 是 io.Reader 的子類型。
Golang 的設計決策
Golang 決定不完全實現協方差是基於安全考量。允許協變可能會導致使用與預期簽名不匹配的類型呼叫函數,從而導致未定義的行為。
常見問題解答說明
Golang 常見問題解答明確指出當前的行為是故意的而不是錯誤。此決定旨在防止可能損害應用程式可靠性的意外運行時錯誤。
可轉換類型與協變類型
雖然 Golang 不支援完全協變,但它允許一種類型到另一種類型的轉換。但是,在 func Pipe 的情況下,無法使用類型參數來表示此轉換。
作為替代方案,您可以將 left 的結果明確轉換為 right 所需的類型。然而,這種方法在編譯時不是型別安全的,如以下修改後的程式碼所示:
雖然這可以完成工作,但它犧牲了執行時間轉換的編譯時安全性。
以上是為什麼 Golang 1.18 泛型不完全支持協方差?的詳細內容。更多資訊請關注PHP中文網其他相關文章!