90 votes

Quelle est la différence entre les fonctions et les méthodes en Go ?

J'essaie de me lancer dans l'utilisation de Go et de l'application documentation est très bon. Ce que je n'ai pas trouvé dans la documentation, c'est la différence entre les fonctions et les méthodes.

D'après ce que je comprends pour l'instant : les fonctions sont "globales", ce qui signifie que je ne dois pas importer un paquet pour utiliser les fonctions, elles sont toujours là. Les méthodes sont liées aux paquets. Est-ce correct ?

138voto

tux21b Points 17336

D'après ce que je comprends pour l'instant : les fonctions sont "globales", ce qui signifie que je ne dois pas importer un paquet pour utiliser les fonctions, elles sont toujours là. Les méthodes sont liées aux paquets. Est-ce correct ?

Non, ce n'est pas correct. Il y a juste quelques fonctions de la intégré qui sont toujours disponibles. Tout le reste doit être importé.

Le terme "méthode" est apparu avec la programmation orientée objet. Dans un langage orienté objet (comme le C++ par exemple), vous pouvez définir une "classe" qui encapsule des données et des fonctions qui vont ensemble. Ces fonctions à l'intérieur d'une classe sont appelées "méthodes" et vous avez besoin d'une instance de cette classe pour appeler une telle méthode.

En Go, la terminologie est fondamentalement la même, bien que Go ne soit pas un langage OOP au sens classique du terme. En Go, une fonction qui prend un récepteur est généralement appelée une méthode (probablement parce que les gens sont encore habitués à la terminologie de la POO).

Donc, par exemple :

func MyFunction(a, b int) int {
  return a + b
}
// Usage:
// MyFunction(1, 2)

mais

type MyInteger int
func (a MyInteger) MyMethod(b int) int {
  return a + b
}
// Usage:
// var x MyInteger = 1
// x.MyMethod(2)

31voto

Salvador Dali Points 11667

La réponse de Tux est géniale, mais je veux l'enrichir avec l'utilisation des méthodes de Go avec struct (car c'est là que je l'ai souvent utilisé). Supposons donc que vous vouliez construire quelque chose pour calculer diverses méthodes sur des triangles. Vous commencez avec un struct :

type Triangle struct {
    a, b, c float64
}

puis vous souhaitez ajouter quelques fonctions pour calculer le périmètre et le carré :

func valid(t *Triangle) error {
    if t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a {
        return nil
    }
    return errors.New("Triangle is not valid")
}

func perimeter(t *Triangle) (float64, error) {
    err := valid(t)
    if err != nil {
        return -1, err
    }

    return t.a + t.b + t.c, nil
}

func square(t *Triangle) (float64, error) {
    p, err := perimeter(t)
    if err != nil {
        return -1, err
    }

    p /= 2
    s := p * (p - t.a) * (p - t.b) * (p - t.c)
    return math.Sqrt(s), nil
}

Et maintenant vous avez votre programme de travail <a href="https://play.golang.org/p/ryAGg6DjY4">Go Playground</a> . Dans ce cas, votre fonction prend un paramètre (pointeur vers un triangle) et fait quelque chose. Dans le monde de la POO, les gens peuvent avoir créé une classe et ensuite ajouté des méthodes. Nous pouvons voir notre structure comme une sorte de classe avec des champs et maintenant nous ajoutons des méthodes :

func (t *Triangle) valid() error {
    if t.a + t.b > t.c && t.a + t.c > t.b && t.b + t.c > t.a {
        return nil
    }
    return errors.New("Triangle is not valid")
}

func (t *Triangle) perimeter() (float64, error) {
    err := t.valid()
    if err != nil {
        return -1, err
    }

    return t.a + t.b + t.c, nil
}

func (t *Triangle) square() (float64, error) {
    p, err := t.perimeter()
    if err != nil {
        return -1, err
    }

    p /= 2
    s := p * (p - t.a) * (p - t.b) * (p - t.c)
    return math.Sqrt(s), nil
}

et nous avons un <a href="https://play.golang.org/p/KUXHWY3Ymh">working example</a> .

Remarquez que cela ressemble vraiment à une méthode pour les objets.

24voto

Anil Kurian Points 105

Ils sont expliqués en détail ici - https://anil.cloud/2017/01/26/golang-functions-methods-simplified/

Une fonction en Go suit la syntaxe suivante :

func FunctionName(Parameters...) ReturnTypes...

Exemple :

func add(x int, y int) int

Pour exécuter :

  add(2,3) 

Une méthode est comme une fonction, mais attachée à un type (appelé récepteur). Le guide officiel indique "Une méthode est une fonction avec un argument récepteur spécial". Le récepteur apparaît entre le mot-clé func et le nom de la méthode. La syntaxe d'une méthode est la suivante :

func (t ReceiverType) FunctionName(Parameters...) ReturnTypes...

Exemple :

func (t MyType) add(int x, int y) int

Pour exécuter :

type MyType string
t1 := MyType("sample")
t1.add(1,2)

Introduisons maintenant les pointeurs dans le tableau. Le langage Go est de type pass by value, ce qui signifie que de nouvelles copies des paramètres sont transmises à chaque appel de fonction/méthode. Pour les passer par référence, vous pouvez utiliser des pointeurs.

Syntaxe de la fonction avec un pointeur dans la liste des arguments/paramètres.

func FunctionName(*Pointers...,Parameters...) ReturnTypes...

Exemple

func add(t *MyType, x int, y int) int

Pour exécuter :

type MyType string
t1 := MyType("sample")
add(&t1,4,5)

De même pour les méthodes, le type de récepteur peut être un pointeur. Syntaxe d'une méthode avec un pointeur (comme récepteur)

func (*Pointer) FunctionName(Parameters...) ReturnTypes...

Exemple

func (t *MyType) add(x int, y int) int

Pour exécuter :

type MyType string
t1 := MyType("sample")
t1.add(2,3)

Notez que nous pouvons toujours écrire t1.add() pour exécuter la méthode avec un pointeur récepteur (même si 't1' n'est pas un pointeur) et Go l'interprétera comme (&t1).add(). De même, une méthode avec un récepteur de valeur peut aussi être appelée en utilisant un pointeur, Go interprétera p.add() comme (*p).add() dans ce cas (où 'p' est un pointeur). Ceci n'est applicable qu'aux méthodes et non aux fonctions.

Les méthodes avec un pointeur récepteur sont très utiles pour obtenir un comportement "Java" où la méthode modifie réellement la valeur vers laquelle le récepteur pointe et non une copie de celle-ci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X