首頁  >  文章  >  後端開發  >  如何在 Go 1.18 泛型中將約束類型作為函數參數傳遞?

如何在 Go 1.18 泛型中將約束類型作為函數參數傳遞?

Linda Hamilton
Linda Hamilton原創
2024-10-27 04:33:30164瀏覽

How to Pass Constrained Types as Function Arguments in Go 1.18 Generics?

在Go 1.18 泛型中將約束類型處理為函數參數

Go 1.18 引入了泛型,允許開發者創建可在任意操作上運行的函數和類型資料類型。但是,當嘗試將約束類型作為參數傳遞給需要具體類型的函數時,編譯器可能會引發錯誤。

為了說明此問題,請考慮以下範例:

<code class="go">type Pokemon interface {
    ReceiveDamage(float64)
    InflictDamage(Pokemon)
}

type Float interface {
    float32 | float64
}

type Charmander[F Float] struct {
    Health      F
    AttackPower F
}</code>

這裡,Charmander 實作了 Pokemon 介面並接受必須是 float32 或 float64 的泛型類型參數 F。

<code class="go">func (c *Charmander[float64]) ReceiveDamage(damage float64) {
    c.Health -= damage
}

func (c *Charmander[float64]) InflictDamage(other Pokemon) {
    other.ReceiveDamage(c.AttackPower)
}</code>

但是,編譯器在 InflictDamage 方法中引發錯誤,指出 c. AttackPower 不能用作 other.ReceiveDamage 函數的 float64 參數。這是因為,儘管將 Charmander 結構體實例化為 *Charmander[float64],編譯器仍然認為 AttackPower 是 F 型。

這個問題的解決方案在於使用型別轉換。 ReceiveDamage 需要一個 float64,但 AttackPower 仍然限制為 F。因此,我們需要將 AttackPower 轉換為 float64:

<code class="go">func (c *Charmander[T]) ReceiveDamage(damage float64) {
    c.Health -= T(damage)
}

func (c *Charmander[T]) InflictDamage(other Pokemon) {
    other.ReceiveDamage(float64(c.AttackPower))
}</code>

這些轉換可以編譯,因為 float64 可轉換為 F 類型集中的所有類型(float32和 float64)。

請注意,如果 T 用 float32 實例化,轉換 T(damage) 可能會導致精度損失。然而,在這個特定的用例中,這不太可能成為一個問題。

以上是如何在 Go 1.18 泛型中將約束類型作為函數參數傳遞?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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