理解Go 泛型中的「不能使用*T 類型的變數作為參數中的類型字串」錯誤
在提供的在程式碼片段中,您正在嘗試一般性地呼叫一個需要stringer 類型參數的函數do,但您正在傳遞一個指向類型參數 T的指標
Go 編譯器會引發錯誤,因為:
-
型別識別與參數: T 本質上並不等於其限制 FooBar。因此,*T 與 *FooBar 或 *bar 不同。
-
缺少方法: stringer 介面需要一個名為 a() 的方法。目前,您的 foo 和 bar 類型在指標接收器上實作了此方法,但 *T 本身並不具有此方法。
修復問題
有兩種解決此問題的主要方法:
1.使用類型斷言類型來斷言類型安全(不太理想)
- 斷言*T 在do函數中使用 any(t).(stringer) 實作 stringer。
- 此方法如果 T 沒有真正實現,可能會導致恐慌縱梁。
2。重新定義約束並自訂泛型(首選)
- 將 stringer 作為約束新增至 FooBar 介面。
- 使用 foo 和 bar 類型的指標接收器來與約束對齊.
- 引入第二個類型參數,用於指定 FooBar 內的約束介面。
- 將約束類型的實例作為參數傳遞給 blah。
修訂的程式碼:
type FooBar[T foo | bar] interface {
*T
stringer
}
func blah[T foo | bar, U FooBar[T]]() {
var t T
do(U(&t))
}
func main() {
blah[foo]()
}
登入後複製
在此修改後的程式碼:
- FooBar 介麵包含stringer 。
- foo 和 bar 類型的 a() 方法有指標接收器。
- U 受 FooBar[T] 約束,確保它符合 FooBar 和 stringer 約束。
- blah 接受 U 型的參數,它是受約束的 FooBar 的實例介面。
以上是為什麼我不能在 Go 泛型中使用 `*T` 類型變數作為 `Stringer`?的詳細內容。更多資訊請關注PHP中文網其他相關文章!