为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Go 1.18 泛型,如何使用约束类型作为需要具体类型的函数的参数?

使用 Go 1.18 泛型,如何使用约束类型作为需要具体类型的函数的参数?

Go
精慕HU 2022-11-23 15:25:33

去版本:1.18


这是一个不是特别有用的愚蠢示例。我将其用作学习泛型的练习。


我有一个Pokemon界面


type Pokemon interface {

    ReceiveDamage(float64)

    InflictDamage(Pokemon)

}

并Charmander带有实现Pokemon接口的类型参数。


type Float interface {

    float32 | float64

}


type Charmander[F Float] struct {

    Health      F

    AttackPower F

}

我想用Charmander的攻击力造成伤害。


func (c *Charmander[float64]) ReceiveDamage(damage float64) {

    c.Health -= damage

}


func (c *Charmander[float64]) InflictDamage(other Pokemon) {

    other.ReceiveDamage(c.AttackPower)

}

我的编译器报错


不能将 c.AttackPower(受 Float 约束的 float64 类型变量)用作 other.ReceiveDamage 编译器(IncompatibleAssign)参数中的 float64 值


我已经将 struct generic 实例化为*Charmander[float64]. 我希望编译器知道AttackPower是一个float64.


当我将 a 传递给float64期望为 的函数时,float64它为什么要抱怨?另一方面,ReceiveDamage不抱怨。我float64从中减去 aHealth是一个受约束的类型。


查看完整描述

1 回答

?
海绵宝宝撒

TA贡献1497条经验 获得超8个赞

您必须使用类型转换。该方法ReceiveDamage需要一个float64,但主要类型在F. 某种类型的东西F,即使仅限于浮点数,或者即使仅限于一个特定的浮点数,也不是float64。它是F。(此外,它也可以用 实例化float32)。


两种转换都可以编译,因为float64可转换为类型参数的类型集中的所有类型,float32和float64,反之亦然。


所以方法变成:


func (c *Charmander[T]) ReceiveDamage(damage float64) {

    c.Health -= T(damage)

}


func (c *Charmander[T]) InflictDamage(other Pokemon) {

    other.ReceiveDamage(float64(c.AttackPower))

}

固定游乐场:https ://go.dev/play/p/FSsdlL8tBLn


当用 实例化时,请注意转换T(damage)可能会导致精度损失。(在这个特定的用例中,这可能不是问题……)Tfloat32


查看完整回答
反对 回复 2022-11-23

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信