首页  >  文章  >  后端开发  >  如何在 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