Définir et implémenter des interfaces
Satisfaction implicite et interface vide
Définir et implémenter des interfaces est une leçon Go Academy gratuite sur CoddyKit. Ceci est la leçon 1 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.
Qu'est-ce qu'une interface ?
Une interface en Go est un ensemble de signatures de méthodes. Tout type qui implémente toutes ces méthodes satisfait implicitement l'interface : aucun mot-clé implements n'est nécessaire. On parle de typage structurel ou de typage par canard.
Déclarer une interface
Définissez une interface avec le mot-clé type :
package main
import "fmt"
type Shape interface {
Area() float64
Perimeter() float64
}
type Circle struct{ Radius float64 }
func (c Circle) Area() float64 { return 3.14159 * c.Radius * c.Radius }
func (c Circle) Perimeter() float64 { return 2 * 3.14159 * c.Radius }
func main() {
var s Shape = Circle{5}
fmt.Printf("Area: %.2f\n", s.Area())
}Satisfaction implicite
Aucune déclaration d'intention n'est nécessaire. Si un type possède les bonnes méthodes, il satisfait automatiquement l'interface :
package main
import "fmt"
type Greeter interface{ Greet() string }
type English struct{}
func (e English) Greet() string { return "Hello" }
type Spanish struct{}
func (s Spanish) Greet() string { return "Hola" }
func say(g Greeter) { fmt.Println(g.Greet()) }
func main() {
say(English{})
say(Spanish{})
}L'interface vide
interface{} (ou any depuis Go 1.18) est satisfaite par tous les types. Elle est utilisée lorsque le type est inconnu au moment de la compilation :
package main
import "fmt"
func printAny(v any) { fmt.Printf("%T: %v\n", v, v) }
func main() {
printAny(42)
printAny("hello")
printAny([]int{1,2,3})
}Valeurs d'interface
Une valeur d'interface contient deux éléments : un type concret et une valeur concrète. Une interface nil a ces deux éléments définis à nil :
package main
import "fmt"
type Animal interface{ Sound() string }
type Dog struct{}
func (d Dog) Sound() string { return "woof" }
func main() {
var a Animal
fmt.Println(a == nil) // true
a = Dog{}
fmt.Println(a == nil) // false
fmt.Println(a.Sound())
}Satisfaction de plusieurs interfaces
Un type peut satisfaire plusieurs interfaces simultanément :
package main
import "fmt"
type Reader interface{ Read() string }
type Writer interface{ Write(string) }
type ReadWriter interface{ Reader; Writer }
type File struct{ content string }
func (f *File) Read() string { return f.content }
func (f *File) Write(s string) { f.content = s }
func main() {
var rw ReadWriter = &File{}
rw.Write("hello")
fmt.Println(rw.Read())
}Affectation d'interfaces
Une interface plus large peut contenir une valeur concrète plus spécifique. L'affectation entre types d'interface exige que le type concret satisfasse les deux interfaces :
package main
import "fmt"
type Stringer interface{ String() string }
type Point struct{ X, Y int }
func (p Point) String() string { return fmt.Sprintf("(%d,%d)", p.X, p.Y) }
func main() {
var s Stringer = Point{3, 4}
fmt.Println(s.String())
}Piège de l'interface nil
Une interface non nulle contenant une valeur concrète nulle n'est NOT égale à nil :
package main
import "fmt"
type MyErr struct{}
func (e *MyErr) Error() string { return "oops" }
func bad() error {
var e *MyErr // nil pointer
return e // returns non-nil interface!
}
func main() {
err := bad()
fmt.Println(err == nil) // false — common gotcha
}Les interfaces facilitent les tests
Définir les dépendances comme des interfaces permet de remplacer les implémentations réelles par des simulations dans les tests :
package main
import "fmt"
type EmailSender interface{ Send(to, body string) error }
type MockSender struct{ Sent []string }
func (m *MockSender) Send(to, body string) error {
m.Sent = append(m.Sent, to)
return nil
}
func notify(s EmailSender, addr string) { s.Send(addr, "hello") }
func main() {
mock := &MockSender{}
notify(mock, "a@b.com")
fmt.Println(mock.Sent) // [a@b.com]
}Accepter des interfaces, retourner des structures
Une bonne pratique en Go : les paramètres des fonctions devraient être des interfaces (pour plus de souplesse), tandis que les types retournés devraient être des types concrets (afin que les appelants sachent ce qu'ils obtiennent) :
package main
type Logger interface{ Log(string) }
type FileLogger struct{}
func (f *FileLogger) Log(s string) {}
func NewFileLogger() *FileLogger { // returns concrete
return &FileLogger{}
}
func process(l Logger) {} // accepts interface
func main() { process(NewFileLogger()) }Garder les interfaces petites
La bibliothèque standard de Go privilégie les interfaces minuscules : io.Reader possède une méthode, et io.Writer en possède une également. Les petites interfaces sont plus faciles à composer et à simuler.
Vérification rapide
Un type doit-il déclarer qu'il implémente une interface ?
Récapitulatif : interfaces
Points essentiels :
- Les interfaces définissent un comportement, pas des données
- La satisfaction est implicite : aucun mot-clé
implements - L'interface vide (
any) accepte tous les types - Méfiez-vous du piège de l'interface
nil - Gardez les interfaces petites et ciblées
Exercice pratique
Définissez une interface Storage avec Save(key, value string) error et Load(key string) (string, error). Implémentez-la avec un MemStorage reposant sur une table associative, puis testez-la.
Questions Fréquemment Posées
La leçon « Définir et implémenter des interfaces » est-elle gratuite ?
Oui — le texte complet de « Définir et implémenter des interfaces » 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 « Définir et implémenter des interfaces » ?
Satisfaction implicite et interface vide 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 1 sur 4.
Combien de temps prend la leçon « Définir et implémenter des interfaces » ?
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
- Définir et implémenter des interfaces
- Interfaces essentielles de la bibliothèque standard
- Assertions de type et switch de type
- Composition d’interfaces et bonnes pratiques