Home  >  Article  >  Backend Development  >  How Can I Use Constrained Types as Arguments in Go Functions When They Expect Concrete Types?

How Can I Use Constrained Types as Arguments in Go Functions When They Expect Concrete Types?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-27 07:15:29185browse

 How Can I Use Constrained Types as Arguments in Go Functions When They Expect Concrete Types?

Using Constrained Types as Arguments in Go 1.18 Generics

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn