首頁 > 後端開發 > Golang > 為什麼我不能在 Go 泛型中使用 `*T` 類型變數作為 `Stringer`?

為什麼我不能在 Go 泛型中使用 `*T` 類型變數作為 `Stringer`?

Mary-Kate Olsen
發布: 2024-12-13 01:58:10
原創
918 人瀏覽過

Why Can't I Use a `*T` Type Variable as a `Stringer` in Go Generics?

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

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