Maison  >  Article  >  développement back-end  >  Comment puis-je utiliser des types contraints comme arguments dans les fonctions Go lorsqu'elles attendent des types concrets ?

Comment puis-je utiliser des types contraints comme arguments dans les fonctions Go lorsqu'elles attendent des types concrets ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-27 07:15:29185parcourir

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

Utilisation de types contraints comme arguments dans les génériques Go 1.18

Dans Go 1.18, les génériques ont introduit la possibilité de contraindre les paramètres de type, permettant une plus grande flexibilité et une plus grande sécurité de type. Cependant, lors de l'utilisation de types contraints comme arguments pour des fonctions attendant des types concrets, un comportement inattendu peut survenir.

Considérez l'exemple suivant, où nous définissons une interface Pokémon et une structure Charmander avec un paramètre de type contraint à Float (float32 ou 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>

Notre objectif est d'utiliser le champ AttackPower de Charmander pour infliger des dégâts dans la méthode InflictDamage. Cependant, lors de l'implémentation de cette méthode, nous rencontrons l'erreur suivante :

cannot use c.AttackPower (variable of type float64 constrained by Float) as float64 value in argument to other.ReceiveDamage compiler(IncompatibleAssign)

Cette erreur survient car, malgré l'instanciation de la structure Charmander en tant que *Charmander[float64], le champ AttackPower est toujours de type F, ce qui est limité à Float. Dans ce contexte, Float englobe à la fois float32 et float64, et le compilateur ne peut pas automatiquement convertir entre eux.

Pour résoudre ce problème, nous devons convertir explicitement le champ AttackPower en float64, le type attendu pour l'autre.ReceiveDamage argument de méthode :

<code class="go">func (c *Charmander[T]) InflictDamage(other Pokemon) {
    other.ReceiveDamage(float64(c.AttackPower))
}</code>

Cette conversion garantit que la valeur de AttackPower est correctement transmise à la méthode other.ReceiveDamage. De plus, nous devons convertir le paramètre Damage en type F dans la méthode ReceiverDamage pour maintenir la cohérence du type :

<code class="go">func (c *Charmander[T]) ReceiveDamage(damage float64) {
    c.Health -= T(damage)
}</code>

En implémentant ces conversions de type, nous pouvons utiliser des types contraints comme arguments pour les fonctions attendant des types concrets, tandis que maintenir la sécurité des types et éviter les erreurs du compilateur. Il est important de noter que les conversions de types peuvent entraîner une perte de précision lors de la conversion entre différents types float.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn