Dans sa forme la plus simple, un type interface est un ensemble de signatures de méthodes.
Voici un exemple de définition d'interface qui comprend deux méthodes Add et Value :
type Counter interface {
Add(increment int)
Value() int
}
Les noms de paramètres comme increment peuvent être omis dans la définition de l'interface, mais ils améliorent souvent la lisibilité.
En Go, les noms d'interface ne contiennent pas le mot Interface ni I.
En revanche, ils se terminent souvent par er, comme Reader ou Stringer.
Tout type qui définit les méthodes de l'interface « implémente » automatiquement et implicitement cette interface.
Il n'existe pas de mot-clé implements en Go.
Le type suivant implémente l'interface Counter vue plus haut.
type Stats struct {
value int
// ...
}
func (s Stats) Add(v int) {
s.value += v
}
func (s Stats) Value() int {
return s.value
}
func (s Stats) SomeOtherMethod() {
// The type can have additional methods not mentioned in the interface.
}
Pour implémenter l'interface, le fait que la méthode ait un récepteur de valeur ou un récepteur de pointeur n'a pas d'importance. (Reviens sur les concepts des méthodes si tu as un doute à ce sujet.)
Une valeur de type interface peut contenir n'importe quelle valeur qui implémente ces méthodes. [^1]
Cela signifie que Stats peut désormais être utilisé partout où l'on attend l'interface Counter.
func SetUpAnalytics(counter Counter) {
// ...
}
stats := Stats{}
SetUpAnalytics(stats)
// works because Stats implements Counter
Comme les interfaces sont implémentées implicitement, un type peut facilement implémenter plusieurs interfaces. Il lui suffit de définir toutes les méthodes nécessaires.
Il existe un type d'interface très particulier en Go : le type interface vide, qui ne contient aucune méthode.
L'interface vide s'écrit comme ceci : interface{}.
any est un alias de interface{}, et il est plus couramment utilisé.
Comme l'interface vide n'a aucune méthode, tout type l'implémente implicitement. C'est utile pour définir une fonction qui peut accepter n'importe quelle valeur de façon générique. Dans ce cas, le paramètre de la fonction utilise le type interface vide.
Le nouvel aéroport de Berlin a recruté des développeurs pour son laboratoire de robotique, et tu y commences ton travail. Il dispose de robots maladroits, à l'allure quelque peu humanoïde, qu'il essaie d'utiliser pour améliorer le service client.
Ta première mission consiste à écrire un programme pour que le robot puisse saluer les gens dans leur langue maternelle après qu'ils ont scanné leur passeport à la borne d'enregistrement automatique.
Le robot est fier de ses capacités, alors il annonce toujours d'abord la langue qu'il parle, puis il salue la personne. Par exemple, si quelqu'un scanne un passeport allemand, le robot dira :
I can speak German: Hallo Dietrich!
Tu n'écriras pas toi-même le code des différentes langues, tu dois donc structurer le code du robot pour que d'autres développeurs puissent facilement ajouter d'autres langues par la suite.
Pour commencer, définis une interface Greeter avec deux méthodes.
LanguageName, qui renvoie le nom de la langue (une string) dans laquelle le robot est censé accueillir le visiteur.Greet, qui prend le nom d'un visiteur (une string) et renvoie une string contenant le message de salutation dans une langue spécifique.Ensuite, implémente une fonction SayHello qui prend en arguments le nom du visiteur et tout ce qui implémente l'interface Greeter, et qui renvoie la string de salutation souhaitée.
Par exemple, imagine une implémentation de Greeter en allemand pour laquelle LanguageName renvoie "German" et Greet renvoie "Hallo {name}!" :
SayHello("Dietrich", germanGreeter)
// => "I can speak German: Hallo Dietrich!"
Maintenant, ton travail consiste à faire fonctionner le robot pour les personnes qui scannent un passeport italien.
Pour cela, crée une structure Italian et implémente les deux méthodes nécessaires pour que cette structure satisfasse l'interface Greeter que tu as mise en place dans la tâche 1.
Tu peux saluer quelqu'un en italien avec "Ciao {name}!".
Avant de terminer ta journée, tu dois aussi finir la fonctionnalité qui permet de saluer les gens en portugais.
Pour cela, crée une structure Portuguese et implémente ici aussi les deux méthodes nécessaires pour que cette structure satisfasse l'interface Greeter.
Tu peux saluer quelqu'un en portugais avec "Olá {name}!".
Inscris-toi sur Exercism pour apprendre et maîtriser Go avec 34 concepts166 exercices, et un vrai mentorat humain, le tout gratuitement.