In Go 1.18, generics have introduced the ability to constrain type parameters, allowing for greater flexibility and type safety. However, when using constrained types as arguments to functions expecting concrete types, some unexpected behavior can arise.
Consider the following example, where we define a Pokemon interface and a Charmander struct with a type parameter constrained to Float (float32 or float64):
<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>
Our goal is to use the AttackPower field of Charmander to inflict damage in the InflictDamage method. However, when implementing this method, we encounter the following error:
cannot use c.AttackPower (variable of type float64 constrained by Float) as float64 value in argument to other.ReceiveDamage compiler(IncompatibleAssign)
This error arises because, despite instantiating the Charmander struct as *Charmander[float64], the AttackPower field is still of type F, which is constrained to Float. In this context, Float encompasses both float32 and float64, and the compiler cannot automatically convert between them.
To resolve this issue, we need to explicitly convert the AttackPower field to float64, the expected type for the other.ReceiveDamage method argument:
<code class="go">func (c *Charmander[T]) InflictDamage(other Pokemon) { other.ReceiveDamage(float64(c.AttackPower)) }</code>
This conversion ensures that the value of AttackPower is correctly passed to the other.ReceiveDamage method. Additionally, we need to convert the damage parameter to type F in the ReceiveDamage method to maintain type consistency:
<code class="go">func (c *Charmander[T]) ReceiveDamage(damage float64) { c.Health -= T(damage) }</code>
By implementing these type conversions, we can use constrained types as arguments to functions expecting concrete types, while maintaining type safety and avoiding compiler errors. It's important to note that type conversions may result in precision loss when converting between different float types.
The above is the detailed content of How Can I Use Constrained Types as Arguments in Go Functions When They Expect Concrete Types?. For more information, please follow other related articles on the PHP Chinese website!