Maison >développement back-end >Golang >Pourquoi un récepteur de pointeur dans la méthode String conduit-il à une boucle morte en Go ?
Récepteur de pointeur vs récepteur de valeur dans la méthode String
Dans Go, la méthode String() est utilisée pour contrôler la représentation sous forme de chaîne d'un élément personnalisé taper. Lors de la définition de la méthode String(), il est crucial de comprendre la différence entre un récepteur de pointeur et un récepteur de valeur.
Considérez le code suivant :
type TT struct { a int b float32 c string } func (t *TT) String() string { return fmt.Sprintf("%+v", *t) }
Dans ce code, le String( ) a un récepteur de pointeur, ce qui signifie qu'elle fonctionne sur un pointeur vers une valeur TT. L'appel de tt.String() appelle effectivement (*tt).String().
Maintenant, envisagez de modifier la méthode String() comme suit :
func (t *TT) String() string { return fmt.Sprintf("%+v", t) }
Cette modification supprime le pointeur récepteur, faisant fonctionner la méthode String() sur une valeur de type TT.
Pourquoi cela entraîne-t-il un message mort loop?
Le package fmt vérifie si la valeur en cours d'impression implémente l'interface Stringer (ou a une méthode String()). Si tel est le cas, il appellera cette méthode pour obtenir la représentation sous forme de chaîne. Cependant, dans ce cas, nous avons un récepteur de pointeur pour la méthode String().
Lorsque nous appelons tt.String(), le package fmt transmet une valeur de type *TT. Cependant, la méthode String() attend une valeur de type TT. Cette inadéquation amène le package fmt à appeler à nouveau la méthode String(), qui à son tour sera appelée à nouveau, et ainsi de suite, entraînant une boucle infinie.
Prévention/Protection
Pour éviter cette boucle morte, assurez-vous que le type de récepteur de la méthode String() correspond au type de la valeur transmise au package fmt. Si, pour une raison quelconque, vous devez utiliser le même type de récepteur, vous pouvez créer un nouveau type à l'aide du mot-clé type et convertir la valeur en nouveau type avant d'appeler fmt.Sprintf :
func (t TT) String() string { type TT2 TT return fmt.Sprintf("%+v", TT2(t)) }
En créant un nouveau type, nous supprimons toutes les méthodes du type sous-jacent, brisant efficacement le cycle et nous permettant d'appeler en toute sécurité fmt.Sprintf.
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!