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