Maison >développement back-end >Golang >Comment appeler correctement des méthodes sur des pointeurs d'interface dans Go ?

Comment appeler correctement des méthodes sur des pointeurs d'interface dans Go ?

DDD
DDDoriginal
2024-12-14 19:31:11205parcourir

How to Correctly Call Methods on Interface Pointers in Go?

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!

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