Maison >développement back-end >Golang >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 » ?

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 » ?

DDD
DDDoriginal
2024-11-16 01:10:02243parcourir

Why Does Changing a Method Receiver from Pointer to Non-Pointer Lead to a Dead Loop When Using `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!

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