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