0Pricing
Go Academy · Leçon

Récepteurs pointeurs sur les méthodes

Modifier l’état d’un struct grâce aux récepteurs pointeurs

Récepteurs pointeurs sur les méthodes est une leçon Go Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Go Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Go Academy comprend 4 leçons au total.

Récapitulatif : récepteur de valeur ou de pointeur

Un récepteur de valeur travaille sur une copie de la structure. Un récepteur de pointeur travaille sur l'originale. Utilisez des récepteurs de pointeur dès qu'une méthode doit modifier l'état.

Modification avec un récepteur de pointeur

Seul un récepteur de pointeur peut modifier la structure :

package main
import "fmt"

type Stack struct{ items []int }

func (s *Stack) Push(v int) { s.items = append(s.items, v) }
func (s *Stack) Pop() int {
    n := len(s.items) - 1
    v := s.items[n]
    s.items = s.items[:n]
    return v
}

func main() {
    var st Stack
    st.Push(1); st.Push(2)
    fmt.Println(st.Pop()) // 2
}

Règle de cohérence

Si une méthode d'un type nécessite un récepteur de pointeur, toutes les méthodes doivent utiliser des récepteurs de pointeur. Les mélanger crée des problèmes de satisfaction des interfaces :

package main
import "fmt"

type Counter struct{ n int }

func (c *Counter) Inc()   { c.n++ }   // pointer
func (c *Counter) Val() int { return c.n } // pointer too

func main() {
    c := &Counter{}
    c.Inc(); c.Inc()
    fmt.Println(c.Val()) // 2
}

Satisfaction d'une interface

Une méthode avec récepteur de pointeur appartient uniquement à l'ensemble de méthodes de *T, et non à celui de T. Cela affecte la satisfaction des interfaces :

package main
import "fmt"

type Writer interface{ Write([]byte) }

type File struct{ name string }
func (f *File) Write(b []byte) { fmt.Println(string(b)) }

func main() {
    var w Writer = &File{"out.txt"} // OK
    // var w Writer = File{} — compile error
    w.Write([]byte("hello"))
}

Prise d'adresse automatique

Go prend automatiquement l'adresse lors de l'appel d'une méthode avec récepteur de pointeur sur une valeur adressable :

package main
import "fmt"

type Box struct{ V int }
func (b *Box) Double() { b.V *= 2 }

func main() {
    b := Box{5}
    b.Double()          // Go does (&b).Double()
    fmt.Println(b.V)    // 10
}

Valeurs dont l'adresse ne peut pas être prise

Vous ne pouvez pas appeler de méthodes avec récepteur de pointeur sur des valeurs dont l'adresse ne peut pas être prise (éléments d'une table associative, valeurs retournées par une fonction qui ne sont pas affectées à des variables) :

package main

type T struct{ V int }
func (t *T) Set(v int) { t.V = v }

func getT() T { return T{} }

func main() {
    var t T
    t.Set(1)       // OK — t is addressable
    // getT().Set(1) — ERROR: cannot take address of getT()
    _ = t
}

Récepteurs de grandes structures

Utilisez toujours des récepteurs de pointeur pour les grandes structures afin d'éviter des copies coûteuses à chaque appel de méthode :

package main

type Image struct{ pixels [1024][1024]uint8 }

// Value receiver copies 1MB per call!
func (img Image) Bad() uint8 { return img.pixels[0][0] }

// Pointer receiver — zero copy
func (img *Image) Good() uint8 { return img.pixels[0][0] }

func main() { _ = Image{} }

Récepteurs de pointeur nil

Les méthodes avec récepteurs de pointeur peuvent gérer nil correctement :

package main
import "fmt"

type List struct{ head *node }
type node struct{ val int; next *node }

func (l *List) Len() int {
    if l == nil { return 0 }
    count := 0
    for n := l.head; n != nil; n = n.next { count++ }
    return count
}

func main() {
    var l *List
    fmt.Println(l.Len()) // 0
}

Intégration et récepteurs de pointeur

Lorsque vous intégrez un type avec des récepteurs de pointeur, la structure englobante doit elle aussi être utilisée comme pointeur pour accéder aux méthodes promues :

package main
import "fmt"

type Base struct{ V int }
func (b *Base) Set(v int) { b.V = v }

type Derived struct{ Base }

func main() {
    d := &Derived{}
    d.Set(42)           // promoted pointer-receiver method
    fmt.Println(d.V)    // 42
}

Copie des mutex

Ne copiez jamais une structure qui contient un sync.Mutex : utilisez toujours un récepteur de pointeur ou transmettez-la par pointeur. Copier un mutex verrouillé provoque un interblocage :

package main
import "sync"

type Safe struct {
    mu sync.Mutex
    v  int
}

// Correct: pointer receiver
func (s *Safe) Set(v int) {
    s.mu.Lock()
    defer s.mu.Unlock()
    s.v = v
}

func main() { _ = Safe{} }

go vet détecte les erreurs

Exécutez go vet ./... pour détecter les erreurs courantes liées aux récepteurs de pointeur, comme la copie de mutex et de verrous. Cela fait partie des chaînes de traitement de go build et des contrôles d'intégration continue.

Vérification rapide

Dans l'ensemble de méthodes de quels types une méthode avec récepteur de pointeur se trouve-t-elle ?

Récapitulatif

Points essentiels :

  • Les récepteurs de pointeur modifient l'état ; les récepteurs de valeur ne le font pas
  • Utilisez le même type de récepteur pour toutes les méthodes d'un type
  • Seul *T satisfait les interfaces qui nécessitent des méthodes avec récepteur de pointeur
  • Ne copiez jamais de structures contenant des mutex : utilisez des récepteurs de pointeur

Exercice pratique

Implémentez une structure Queue avec les méthodes Enqueue(int), Dequeue() (int, bool) et Len() int, toutes dotées d'un récepteur de pointeur et reposant sur une tranche []int.

Questions Fréquemment Posées

La leçon « Récepteurs pointeurs sur les méthodes » est-elle gratuite ?

Oui — le texte complet de « Récepteurs pointeurs sur les méthodes » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Go Academy, passe à CoddyKit PRO. Le cours Go Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Récepteurs pointeurs sur les méthodes » ?

Modifier l’état d’un struct grâce aux récepteurs pointeurs Tu pratiques Go Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Go Academy ?

Aucune expérience préalable n'est requise. Go Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Récepteurs pointeurs sur les méthodes » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Go Academy ?

Oui. Chaque leçon Go Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Que sont les pointeurs ?
  2. Pointeurs et fonctions
  3. Récepteurs pointeurs sur les méthodes
  4. new() et quand utiliser les pointeurs
← Retour à Go Academy