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

Patricia Arquette
Release: 2024-10-27 07:15:29
Original
261 people have browsed it

 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>
Copy after login

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)
Copy after login

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>
Copy after login

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>
Copy after login

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!

source:php.cn
Statement of this Website
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template