Appel de méthodes sur des pointeurs d'interface dans Go
Dans Go, lors de la programmation sur des interfaces, vous pouvez rencontrer des situations où vous devez pouvoir appeler des méthodes sur un pointeur vers une valeur d’interface. Cela peut survenir dans les cas où vous souhaitez accéder à des méthodes sous-jacentes qui ne sont pas directement exposées par l'interface elle-même.
Considérez le scénario suivant :
package main import "fmt" // SqlExecutor interface type SqlExecutor interface { Get(i interface{}, key interface{}) (interface{}, error) } // GorpDbMap and GorpTransaction implement SqlExecutor type GorpDbMap struct{} type GorpTransaction struct{} func (db GorpDbMap) Get(i interface{}, key interface{}) (interface{}, error) { return nil, nil } func (tx GorpTransaction) Get(i interface{}, key interface{}) (interface{}, error) { return nil, nil } func main() { // Initialize a GorpDbMap or GorpTransaction dbMap := GorpDbMap{} transaction := GorpTransaction{} // Create a repository that uses the SqlExecutor interface repo := Repository{ // This will result in an error Gorp: &dbMap, } // Try to call Get method on the pointer to the SqlExecutor interface obj, err := repo.GetById(1, 2) if err != nil { fmt.Println(err) } fmt.Println(obj) } // Repository demonstrates calling methods on interface pointers type Repository struct { Gorp SqlExecutor } func (r Repository) GetById(i interface{}, key interface{}) interface{} { obj, err := r.Gorp.Get(i, key) if err != nil { panic(err) } return obj }
Lors de l'exécution du code ci-dessus, vous rencontrez l'erreur suivante :
r.Gorp.Get undefined (type *gorp.SqlExecutor has no field or method Get)
Cette erreur se produit car le pointeur vers la valeur de l'interface SqlExecutor n'est pas correctement déréférencé avant d'appeler Get méthode.
Pour résoudre ce problème, vous devez déréférencer le pointeur vers la valeur de l'interface en utilisant l'opérateur astérisque (*). Cela peut être accompli en modifiant le code comme suit :
func main() { // Initialize a GorpDbMap or GorpTransaction dbMap := GorpDbMap{} transaction := GorpTransaction{} // Create a repository that uses the SqlExecutor interface repo := Repository{ Gorp: &dbMap, } // Try to call Get method on the pointer to the SqlExecutor interface obj, err := (*repo.Gorp).Get(1, 2) if err != nil { fmt.Println(err) } fmt.Println(obj) }
En déréférençant le pointeur vers la valeur de l'interface, vous pouvez désormais accéder aux méthodes sous-jacentes de la structure qui implémente l'interface. Dans ce cas, la méthode Get de la structure GorpDbMap est appelée avec succès.
Il est important de noter qu'en Go, il est généralement recommandé de privilégier le passage de valeurs par valeur plutôt que le passage de pointeurs vers des valeurs. Cela permet d'éviter des modifications involontaires des valeurs d'origine. Dans le cas des interfaces, vous devez généralement transmettre la valeur de l'interface elle-même, plutôt qu'un pointeur vers la valeur de l'interface.
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!