首頁 >後端開發 >Golang >為什麼我的 Go 泛型類型參數不滿足 `stringer` 介面?

為什麼我的 Go 泛型類型參數不滿足 `stringer` 介面?

Susan Sarandon
Susan Sarandon原創
2024-12-25 11:10:13488瀏覽

Why Doesn't My Go Generic Type Parameter Satisfy the `stringer` Interface?

理解 Go 中的泛型類型約束

在 Go 1.18 中,泛型提供了增強程式碼彈性的強大工具。但是,在使用類型約束時,了解為什麼會發生某些錯誤非常重要。

問題

考慮以下程式碼:

type stringer interface {
    a() string
}

func do(s stringer) {
    fmt.Println(s.a())
}

func blah[T FooBar]() {
    t := &T{}
    do(t)
}

func main() {
    blah[foo]()
}

嘗試編譯時這段程式碼,你可能會遇到錯誤:

cannot use t (variable of type *T) as type stringer in argument to do: *T does not implement stringer (type *T is pointer to type parameter, not type parameter)

理解錯誤

此錯誤源自於對泛型類型限制如何運作的誤解。 blah 函數中的約束 FooBar 是滿足 FooBar 介面的類型的佔位符。然而,變數 t 的類型為 T,它是指向型別參數 T 的指標。這意味著 T 本身不是類型參數,因此它不能滿足 stringer 介面。

這個問題的解決方案是引入型別參數T和stringer介面之間的關係。有兩種可能的方法:

1。明確斷言

您可以使用任何型別轉換明確斷言 *T 滿足 stringer 介面:

func blah[T FooBar]() {
    t := &T{}
    do(any(t).(stringer))
}

2。類型組合

或者,您可以定義一個結合了FooBar 和stringer 約束的新類型:

type FooBar[T foo | bar] interface {
    *T
    stringer
}

func blah[T foo | bar, U FooBar[T]]() {
    var t T
    do(U(&t))
}

這種方法透過將stringer 嵌入到FooBar 介面中來確保類型安全,並且要求 T是指標類型以滿足約束FooBar.

結論

理解類型約束和類型參數之間的關係對於在 Go 中有效使用泛型至關重要。透過明確斷言或類型組合引入 T 和 stringer 之間的關係,您可以解決錯誤並啟用所需的行為。

以上是為什麼我的 Go 泛型類型參數不滿足 `stringer` 介面?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn