ProgrammationDéveloppeur Go

Comment fonctionnent les méthodes pour les structures en Go ? Quelle est la différence entre la déclaration d'une méthode et celle d'une fonction, et comment les méthodes sont-elles implémentées pour les types basés sur des alias (type alias) ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Go, les méthodes sont des fonctions avec un receiver (récepteur), indiquant à quel type la méthode appartient :

type User struct { Name string } func (u *User) SayHello() { fmt.Println("Salut,", u.Name) }
  • Une méthode est liée à un type spécifique (par exemple, User), tandis qu'une fonction ne l'est pas.
  • Le récepteur de la méthode ((u *User)) fonctionne comme le premier argument d'une fonction, mais la syntaxe et les appels diffèrent.

Important ! Les méthodes ne peuvent être déclarées que pour des types définis dans votre package (pas de méthodes sur un type défini dans un autre package, y compris les types intégrés). Le comportement avec les alias (type alias) est particulier :

  • Pour les nouveaux types basés sur des types existants (type MyInt int), vous pouvez ajouter des méthodes.
  • Pour les type alias (type MyInt = int), vous ne pouvez pas ajouter de méthodes, car c'est juste un alias.

Exemple :

type MyInt int func (m MyInt) Double() int { return int(m) * 2 } // Type alias type MyIntAlias = int // func (m MyIntAlias) Double() int { ... } // erreur de compilation

Question piège

Peut-on déclarer une méthode pour un tableau de type []int ou pour un type alias ?

Réponse : Pour un tableau de type intégré ([]int), il n'est pas possible de déclarer des méthodes. Pour un nouveau type utilisateur basé sur un tableau — c'est possible :

type MySlice []int func (s MySlice) Sum() int { ... } // autorisé

Pour le type alias, c'est impossible :

type SuperSlice = []int // func (s SuperSlice) Sum() int { ... } // erreur

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet


Histoire

Dans un projet de microservices, l'équipe a défini un type alias pour int64 (pour les identifiants) et a tenté de déclarer des méthodes de validation directement pour celui-ci — le code ne s'est pas compilé, il a fallu refactoriser toutes les structures pour prendre en charge les méthodes.

Histoire

Dans un projet backend, des méthodes ont été écrites pour un tableau personnalisé, mais par accident, un nouveau type (type ... []T) n'a pas été défini, et ils ont travaillé avec le []T intégré, ce qui les a empêchés d'ajouter aucune méthode pour travailler avec les éléments du tableau.

Histoire

En essayant d'ajouter des méthodes aux types d'un package externe (par exemple, time.Time) pour standardiser le travail avec des dates, il est devenu évident que cela n'était pas possible en Go — il a fallu utiliser la composition et des fonctions utilitaires.