Aller au contenu
Développement medium

Méthodes et récepteurs en Go

8 min de lecture

Go

Une méthode est une fonction attachée à un type : elle lui donne un comportement. Ce guide vous montre comment définir des méthodes en Go et, surtout, comment choisir le récepteur : valeur ou pointeur. Ce choix décide si la méthode peut modifier l'objet, et il conditionnera plus tard la façon dont votre type satisfait une interface. Public visé : vous connaissez les structures et les pointeurs. Exemples testés sur Go 1.26.

  • Définir une méthode sur un type.
  • Choisir un récepteur valeur ou pointeur en connaissance de cause.
  • Appliquer la règle de cohérence des récepteurs.
  • Attacher une méthode à un type qui n'est pas une struct.

Une méthode ressemble à une fonction, avec un récepteur déclaré entre func et le nom : la variable qui représente l'objet sur lequel la méthode agit.

type Compteur struct {
n int
}
// (c Compteur) est le récepteur : lecture seule
func (c Compteur) Valeur() int {
return c.n
}

On l'appelle ensuite avec la notation pointée : c.Valeur(). Le récepteur c joue le rôle du this/self d'autres langages, mais il est nommé explicitement et vous choisissez son type.

Récepteur valeur ou pointeur : le choix qui compte

Section intitulée « Récepteur valeur ou pointeur : le choix qui compte »

C'est le point central. Un récepteur valeur (c Compteur) reçoit une copie : la méthode peut lire mais pas modifier l'objet. Un récepteur pointeur (c *Compteur) reçoit l'adresse : la méthode peut modifier l'objet original.

// récepteur POINTEUR : peut modifier
func (c *Compteur) Increment() { c.n++ }
// récepteur VALEUR : lecture seule
func (c Compteur) Valeur() int { return c.n }
func main() {
c := Compteur{}
c.Increment()
c.Increment()
c.Increment()
fmt.Println(c.Valeur()) // 3
}

Increment a un récepteur pointeur : chaque appel modifie bien le compteur, qui atteint 3. Si son récepteur était une valeur (c Compteur), il incrémenterait une copie jetée aussitôt, et Valeur() renverrait toujours 0. La règle pratique : une méthode qui modifie l'objet doit avoir un récepteur pointeur.

Vous avez peut-être remarqué qu'on écrit c.Increment() et non (&c).Increment(), alors que le récepteur est un pointeur. Go prend automatiquement l'adresse quand c'est nécessaire, tant que c est une variable adressable. Vous n'avez donc pas à jongler avec & à chaque appel : le compilateur s'en charge.

Une convention forte en Go : tous les récepteurs d'un même type doivent être du même genre, soit tous valeur, soit tous pointeur. Mélanger prête à confusion et pose problème dès qu'on utilise le type derrière une interface. En pratique, dès qu'une seule méthode a besoin d'un récepteur pointeur, on met toutes les méthodes du type en récepteur pointeur.

Une méthode n'est pas réservée aux structs. Vous pouvez en attacher à n'importe quel type nommé que vous définissez, y compris à partir d'un type de base.

type Celsius float64
func (c Celsius) EnFahrenheit() float64 {
return float64(c)*9/5 + 32
}
func main() {
t := Celsius(37)
fmt.Printf("%.1f°F\n", t.EnFahrenheit()) // 98.6°F
}

En nommant un type (type Celsius float64), on peut lui donner des méthodes qui expriment son domaine métier. C'est plus lisible et plus sûr qu'un float64 nu dont on ne sait pas s'il représente des degrés, des euros ou des secondes.

Cet exercice met en jeu les deux types de récepteurs. Cherchez la solution avant d'ouvrir la réponse.

Créez un type Rectangle avec deux champs Largeur et Hauteur (float64), et deux méthodes :

  • Aire() qui renvoie la surface (largeur × hauteur), sans rien modifier.
  • Agrandir(f float64) qui multiplie largeur et hauteur par le facteur f.

Vérifiez qu'un rectangle 3×4 a une aire de 12, puis 48 après Agrandir(2).

Indice : réfléchissez à quel récepteur (valeur ou pointeur) convient à chaque méthode selon qu'elle lit ou modifie.

  • Une méthode est une fonction avec un récepteur déclaré entre func et le nom.
  • Récepteur valeur = copie en lecture seule ; récepteur pointeur = peut modifier l'objet original.
  • Une méthode qui mute l'objet doit avoir un récepteur pointeur.
  • Cohérence : tous les récepteurs d'un type doivent être du même genre ; en cas de doute, tout en pointeur.
  • On peut attacher une méthode à tout type nommé, pas seulement aux structs, pour exprimer un domaine métier.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn