Récepteurs de pointeurs dans Golang et implémentation d'interface
Dans Go, les fonctions de récepteur permettent aux méthodes d'opérer sur des types spécifiques. Lorsqu'une méthode dispose d'un récepteur de pointeur, elle peut modifier l'instance réelle de la structure.
Comprendre le problème
Considérez l'extrait de code suivant :
type IFace interface { SetSomeField(newValue string) GetSomeField() string } type Implementation struct { someField string } // Method with non-pointer receiver func (i Implementation) GetSomeField() string { return i.someField } // Method with non-pointer receiver func (i Implementation) SetSomeField(newValue string) { i.someField = newValue }
Dans ce code, les deux méthodes ont des récepteurs sans pointeur. Cela signifie que lors de l'appel de SetSomeField, il crée une copie de la structure et modifie cette copie. L'instance d'origine reste inchangée.
Utilisation d'un récepteur de pointeur
Pour modifier l'instance réelle, la méthode SetSomeField doit avoir un récepteur de pointeur :
// Method with pointer receiver func (i *Implementation) SetSomeField(newValue string) { i.someField = newValue }
Maintenant, SetSomeField peut modifier l'instance d'origine. Cependant, cela soulève un problème lors de l'implémentation de l'interface IFace :
package main import ( "fmt" ) type IFace interface { SetSomeField(newValue string) GetSomeField() string } type Implementation struct { someField string } // Method with pointer receiver func (i *Implementation) GetSomeField() string { return i.someField } // Method with pointer receiver func (i *Implementation) SetSomeField(newValue string) { i.someField = newValue } func Create() IFace { obj := Implementation{someField: "Hello"} return obj // Offending line } func main() { a := Create() // Assigning an Implementation value to an IFace variable a.SetSomeField("World") // Will panic because a is an Implementation value, not a pointer fmt.Println(a.GetSomeField()) }
La compilation de ce code entraîne une panique car Create renvoie une valeur d'implémentation, pas un pointeur vers celle-ci. Pour implémenter l'interface avec un récepteur de pointeur, la méthode doit être déclarée comme récepteur de pointeur et la fonction Create doit renvoyer un pointeur vers l'implémentation.
type IFace interface { SetSomeField(newValue string) GetSomeField() string } type Implementation struct { someField string } // Method with pointer receiver func (i *Implementation) GetSomeField() string { return i.someField } // Method with pointer receiver func (i *Implementation) SetSomeField(newValue string) { i.someField = newValue } func Create() *Implementation { obj := Implementation{someField: "Hello"} return &obj } func main() { var a IFace a = Create() // Now assigning a pointer to Implementation to an IFace variable a.SetSomeField("World") fmt.Println(a.GetSomeField()) }
Maintenant, a est un pointeur vers une valeur d'implémentation, qui implémente IFace avec des récepteurs de pointeurs. Les modifications apportées via SetSomeField affecteront l'instance d'origine.
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!