Maison > Article > développement back-end > Pourquoi le changement d'un récepteur de méthode de pointeur à non-pointeur entraîne-t-il une boucle morte lors de l'utilisation de « fmt.Sprintf » ?
Comprendre la différence entre t et *t
Dans cet extrait de code, nous avons un type TT avec une méthode String qui implémente le fmt Interface .Stringer :
package main import "fmt" type TT struct { a int b float32 c string } func (t *TT) String() string { return fmt.Sprintf("%+v", *t) } func main() { tt := &TT{3, 4, "5"} fmt.Printf(tt.String()) }
Ce code fonctionne car le package fmt appelle la méthode String pour obtenir la chaîne représentation de la valeur TT.
Cependant, lorsque la méthode String est modifiée pour prendre un récepteur sans pointeur :
func (t *TT) String() string { return fmt.Sprintf("%+v", t) }
cela provoque une boucle morte. Expliquons pourquoi :
L'appel de fmt.Sprintf("% v", t) transmet une valeur *TT (pointeur vers TT) au package fmt. Étant donné que la méthode TT.String a un récepteur pointeur, le package fmt ne trouvera pas cette méthode dans l'ensemble de méthodes de type *TT.
Changer le récepteur en un type non pointeur signifie que le package fmt recherchez la méthode String dans l’ensemble de méthodes de TT. Cependant, cela conduit à une récursion infinie car la méthode appelée est la même que celle utilisée pour formater la valeur.
Pour éviter ce problème, un nouveau type peut être créé à l'aide du mot-clé type, séparant efficacement les type de récepteur à partir de la valeur transmise au package fmt :
func (t TT) String() string { type TT2 TT return fmt.Sprintf("%+v", TT2(t)) }
Cela fonctionne car le nouveau type créé par le mot-clé type n'a aucune méthode, donc le package fmt n'essaiera pas de invoquez la méthode String sur le nouveau type.
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!