Les interfaces en Go sont un ensemble de méthodes qu'un type doit implémenter pour correspondre à cette interface. Il n'y a pas de mot-clé explicite implements : la compatibilité est structurelle, et non déclarative. Il est possible d'assigner un type réalisant à une variable de type interface uniquement si le type réalise toutes les méthodes de l'interface.
Important : une variable d'interface contient deux pointeurs - sur les données (value) et sur le type (type).
Exemple de déclaration et d'implémentation :
type Printer interface { Print() } type MyPrinter struct{} func (mp MyPrinter) Print() { fmt.Println("impression...") } var p Printer = MyPrinter{} p.Print() // "impression..."
Que se passe-t-il si la variable d'interface est égale à nil ? Quelle est la différence entre "var i interface{} = nil" et "var i interface{}" ?
Une réponse incorrecte fréquente est "les deux valeurs sont nil". En réalité, ce n'est pas le cas :
var i interface{} = nil - la variable est vraiment nil (type=nil, value=nil)var p *MyPrinter = nil; var i Printer = p, alors i != nil, parce que type != nil (à l'intérieur de i - type=*MyPrinter, value=nil), et de nombreuses vérifications comme if i == nil ne fonctionneront pas lorsque vous vous y attendez.Exemple :
var p *MyPrinter = nil var i Printer = p fmt.Println(i == nil) // false !
Histoire
Description: Dans un service, le gestionnaire d'erreurs renvoyait une interface avec une valeur nil, et les clients prenaient l'erreur pour non nulle, entraînant des actions redondantes. Le problème se situait dans la comparaison de l'interface avec nil.
Histoire
Description: Lors de l'écriture de tests, une erreur était commise en vérifiant l'erreur de type interface sur l'égalité avec nil après le retour d'une structure avec des champs nil. Les tests ne détectaient pas les véritables erreurs, ce qui a conduit à l'apparition d'un bug en production.
Histoire
Description: Lors de la migration d'un type d'interface à un autre, on a oublié d'implémenter toutes les méthodes de la nouvelle interface, car il n'y avait pas de implements explicite. Le code se compilait, mais l'interface n'était pas implémentée, certaines fonctions de simulation ont cessé de fonctionner.