Un type ne déclare pas qu'il satisfait une interface. Il l'a, ou il ne l'a pas.A type doesn't declare it satisfies an interface. It has it, or it doesn't.
On quitte la concurrence pour le système de types, et on commence par sa pièce la plus déroutante quand on vient d'ailleurs : l'interface. Dans la plupart des langages, un type annonce les interfaces qu'il implémente — implements Comparable, : IDisposable. En Go, ce lien n'existe pas. Une interface est une liste de méthodes ; tout type qui possède ces méthodes la satisfait, automatiquement, sans le savoir et sans rien signer. La satisfaction est structurelle, pas déclarée. Ça change tout : qui possède l'abstraction, où elle vit, et comment on conçoit ses API.We leave concurrency for the type system, and we start with its most disorienting piece when you come from elsewhere: the interface. In most languages, a type announces the interfaces it implements — implements Comparable, : IDisposable. In Go, that link doesn't exist. An interface is a list of methods; any type holding those methods satisfies it, automatically, without knowing and without signing anything. Satisfaction is structural, not declared. That changes everything: who owns the abstraction, where it lives, and how you design your APIs.
// le réflexe venu des langages à interfaces explicites type Stringer interface { String() string } type Point struct{ X, Y int } // on cherche le mot-clé qui relie le type à l'interface… // class Point implements Stringer ← Java / C# // … ce mot-clé n'existe pas en Go. Il n'y a rien à déclarer.
func (p Point) String() string { // on écrit juste la méthode return fmt.Sprintf("(%d,%d)", p.X, p.Y) } // c'est tout : Point satisfait Stringer, sans l'avoir jamais nommée. // fmt l'accepte déjà — alors que Point n'a jamais entendu parler de fmt.
Le même Buffer satisfait toutes les interfaces dont il a les méthodes, à la fois, sans en citer une seule. On peut même écrire une interface après le type et il la satisfera rétroactivement. L'interface ne vit pas dans le type — elle vit dans le regard qu'on porte sur lui.The same Buffer satisfies every interface whose methods it has, all at once, without naming a single one. You can even write an interface after the type and it will satisfy it retroactively. The interface doesn't live in the type — it lives in how you look at it.
« L'abstraction n'appartient pas à celui qui fournit le type, mais à celui qui le consomme. » Puisqu'un type satisfait une interface sans la déclarer, c'est l'appelant qui choisit l'abstraction qui l'intéresse. Tout le numéro déroule la maxime qui en découle : accepte des interfaces, retourne des structs."The abstraction belongs not to whoever provides the type, but to whoever consumes it." Since a type satisfies an interface without declaring it, the caller picks the abstraction it cares about. The whole issue unrolls the maxim that follows: accept interfaces, return structs.
« Implicite » ne veut pas dire « magique » ou « tardif ». Le compilateur vérifie au moment où tu passes un Point là où une Stringer est attendue : s'il manque une méthode, ça ne compile pas, avec un message qui dit laquelle. Ce n'est pas du duck typing à la Python résolu à l'exécution — c'est du typage structurel statique. La souplesse est dans la déclaration absente, pas dans la sûreté : celle-ci reste totale. Pour forcer la vérification tôt, on écrit var _ Stringer = Point{}.'Implicit' doesn't mean 'magic' or 'late.' The compiler checks at the moment you pass a Point where a Stringer is expected: if a method is missing, it won't compile, with a message naming which one. This isn't Python-style duck typing resolved at runtime — it's static structural typing. The flexibility is in the absent declaration, not in the safety, which stays total. To force the check early, you write var _ Stringer = Point{}.