Comprendre les interfaces en Go
Comprendre les interfaces en Go
Les interfaces en Go sont un concept central qui permet d’écrire du code souple, modulaire et facile à tester. Elles définissent un ensemble de comportements sans préciser comment ces comportements sont implémentés.
🌱 Qu’est-ce qu’une interface ?
Une interface en Go est une collection de méthodes. Une structure (struct) "implémente" une interface implicitement — c’est-à-dire sans mot-clé spécial, dès qu’elle possède les méthodes requises.
package main
import "fmt"
// Définition d'une interface
type Speaker interface {
Speak() string
}
// Une structure qui implémente l'interface
type Dog struct{}
func (d Dog) Speak() string {
return "Woof!"
}
type Cat struct{}
func (c Cat) Speak() string {
return "Meow!"
}
func main() {
// On peut stocker n’importe quelle valeur qui implémente Speaker
var s Speaker
s = Dog{}
fmt.Println(s.Speak()) // "Woof!"
s = Cat{}
fmt.Println(s.Speak()) // "Meow!"
}
🧠 Implémentation implicite
L’un des aspects les plus puissants de Go est que l’implémentation des interfaces est implicite. Pas besoin d’écrire implements ou autre — si une struct a les bonnes méthodes, elle satisfait automatiquement l’interface.
Cela favorise un couplage faible et facilite la composition de comportements.
🔧 Exemple concret : polymorphisme
Grâce aux interfaces, on peut écrire du code qui fonctionne avec différents types, sans les connaître à l’avance :
func MakeItSpeak(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
dog := Dog{}
cat := Cat{}
MakeItSpeak(dog)
MakeItSpeak(cat)
}
Le polymorphisme ici est basé sur le comportement, pas sur l’héritage.
💡 Interface vide
L’interface vide interface{} (ou any depuis Go 1.18) représente tout type.
C’est pratique pour des fonctions génériques ou quand on ne connaît pas le type à l’avance.
func PrintAny(v interface{}) {
fmt.Println(v)
}
func main() {
PrintAny(1)
PrintAny("Hello")
PrintAny(true)
}
🧩 Bonnes pratiques
Garder les interfaces petites : une interface = un comportement.
Définir les interfaces là où elles sont utilisées, pas là où elles sont implémentées.
Préférer la composition à l’héritage.
type Reader interface {
Read() string
}
type Writer interface {
Write(string)
}
type ReadWriter interface {
Reader
Writer
}
🚀 Conclusion
Les interfaces en Go permettent d’écrire du code flexible, testable et modulaire. Elles favorisent la séparation des responsabilités et un style de programmation orienté comportement.