Confusion de l'interface Stringer avec Println : comprendre les objets basés sur des valeurs et ceux basés sur des pointeurs
Question :
Dans un scénario où un objet implémente l'interface Stringer, pourquoi la méthode String de l'objet n'obtient-elle pas invoqué lors de l'utilisation de fmt.Println si l'objet est basé sur une valeur ?
Exemple de code :
Considérez le code Go suivant :
type Car struct { year int make string } func (c *Car) String() string { return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year) } func main() { myCar := Car{year: 1996, make: "Toyota"} fmt.Println(myCar) }
Lorsque myCar est un pointeur, la méthode String est invoquée comme prévu. Cependant, lorsque myCar est une valeur, le formatage Go par défaut est utilisé à la place.
Réponse :
La raison de ce comportement réside dans le fonctionnement des interfaces Go. Lorsque vous spécifiez un type qui implémente une interface (Stringer, dans ce cas), Go s'attend à ce que ce type soit le type exact de l'interface. Lorsque vous transmettez une valeur de type Car à fmt.Println, elle est implicitement convertie en interface{} et il n'y a pas de type Car dans le système de types interface{}. Au lieu de cela, il s'agit d'un type *Car (un pointeur vers Car).
La fonction fmt.Println utilise un commutateur de type pour déterminer comment imprimer la valeur en fonction de son type. Pour une interface Stringer, il vérifie si la valeur implémente la méthode String. Étant donné que Car (basé sur des valeurs) n'implémente pas String, le formatage par défaut est utilisé. Cependant, lorsque vous appelez explicitement myCar.String(), le compilateur le convertit automatiquement en (&myCar).String(), qui a le bon type *Car et appelle la méthode de formatage souhaitée.
Pour garantir que le l'objet est formaté comme vous le souhaitez quel que soit son type, vous avez deux options :
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!