Passer au contenu principal
eLearner.app
Module 5 · Leçon 2 sur 522/50 dans le cours~14 min
Leçons du module (2/5)

Méthodes : récepteur de valeur vs pointeur

Une méthode en Go est une fonction avec un récepteur : un paramètre spécial déclaré entre func et le nom de la méthode, qui lie la méthode à un mec. Il n'y a pas de classes : les méthodes peuvent être définies sur tout type nommé déclaré dans le package actuel.

Syntaxe

Go
type Person struct {
    Name string
}

func (p Person) Greet() string {
    return "ciao " + p.Name
}

p := Person{Name: "Ada"}
fmt.Println(p.Greet())   // "ciao Ada"

Le récepteur p Person fait de Greet une méthode de Person. À l'intérieur du méthode, p est une variable comme les autres.

Récepteur de valeur vs récepteur de pointeur

Go
// VALUE receiver: opera su una COPIA del valore
func (p Person) NameUpper() string {
    return strings.ToUpper(p.Name)
}

// POINTER receiver: opera sul valore originale, può mutarlo
func (p *Person) Rename(n string) {
    p.Name = n
}

Avec le récepteur pointeur, vous pouvez éditer le récepteur et les modifications ils sont vus en dehors de la méthode. Avec le récepteur de valeur non — vous changeriez seulement la copie locale.

Go
p := Person{Name: "Ada"}
p.Rename("Grace")
fmt.Println(p.Name)   // "Grace" — modifica visibile

Quand utiliser le récepteur pointeur

Règles empiriques, par ordre de priorité :

  1. Vous devez changer de récepteur → récepteur pointeur. Obligatoire.
  2. La structure est grande (des dizaines de champs, tableau à l'intérieur) → pointeur récepteur pour éviter des copies coûteuses.
  3. Cohérence : si AU MOINS une méthode du type a un récepteur de pointeur, utilisez récepteur pointeur pour les autres aussi. Convention très importante pour interfaces (Module 6).
  4. Petits types de « valeur » immuables (time.Time, nombres complexes, petits struct) → récepteur de valeur, lisible.

Méthodes sur les types non-struct

Vous pouvez définir des méthodes sur n'importe quel type NAMED déclaré dans votre package :

Go
type Celsius float64

func (c Celsius) ToFahrenheit() float64 {
    return float64(c)*9/5 + 32
}

t := Celsius(20)
fmt.Println(t.ToFahrenheit())  // 68

Vous ne pouvez pas les définir sur des types d'autres packages (ex. int, string) : vous devez créez d’abord un type nommé local.

Essayez-le vous-même

Exercice#go.m5.l2.e1
Tentatives : 0Chargement…

Ajoutez une méthode de chaîne Greet() (récepteur de valeur) à Person qui renvoie « bonjour <Nom> ».

Chargement de l'éditeur…
Afficher l'indice

Récepteur entre parenthèses AVANT le nom de la méthode.

Solution disponible après 3 tentatives

Exercice#go.m5.l2.e2
Tentatives : 0Chargement…

Ajoutez une méthode Rename(n string) avec le récepteur POINTER qui modifie p.Name.

Chargement de l'éditeur…
Afficher l'indice

Récepteur pointeur : `(p *Person)`.

Solution disponible après 3 tentatives

Quiz#go.m5.l2.e3
Prêt

Quand utiliser un récepteur pointeur (p *T) ?

Go
func (t ?T) M() { ... }
Options de réponse

Récapitulatif

  • Méthode = fonction avec un récepteur : func (r T) Nome(...) ... { ... }.
  • Récepteur de valeur : fonctionne sur copie ; Récepteur pointeur : fonctionne sur l'original.
  • Go effectue la conversion T*T automatiquement dans l'appel.
  • Pointeur récepteur quand : modification + grande struct + cohérence avec les autres méthodes du type.
  • Ne mélangez jamais les récepteurs de valeur et de pointeur sur le même type.
  • Les méthodes vont sur les types NAMED dans le package actuel (même non-struct).