Schnittstellen in Go sind eine Menge von Methoden, die ein Typ implementieren muss, um dieser Schnittstelle zu entsprechen. Es gibt kein explizites Schlüsselwort implements: die Kompatibilität ist strukturell, nicht deklarativ. Die Zuweisung eines implementierenden Typs an eine Schnittstellenvariable ist nur möglich, wenn der Typ alle Methoden der Schnittstelle implementiert.
Wichtig: Eine Schnittstellenvariable enthält zwei Zeiger — auf die Daten (value) und auf den Typ (type).
Beispiel für die Deklaration und Implementierung:
type Printer interface { Print() } type MyPrinter struct{} func (mp MyPrinter) Print() { fmt.Println("printing...") } var p Printer = MyPrinter{} p.Print() // "printing..."
Was passiert, wenn die Schnittstellenvariable gleich nil ist? Was unterscheidet "var i interface{} = nil" von "var i interface{}"?
Eine häufig falsche Antwort ist — "beide Werte sind nil". Tatsächlich ist dies nicht der Fall:
var i interface{} = nil — die Variable ist tatsächlich nil (type=nil, value=nil)var p *MyPrinter = nil; var i Printer = p, dann i != nil, weil type != nil (innerhalb von i — type=*MyPrinter, value=nil), und viele Überprüfungen wie if i == nil funktionieren nicht, wenn man es erwartet.Beispiel:
var p *MyPrinter = nil var i Printer = p fmt.Println(i == nil) // false!
Geschichte
Beschreibung: In einem Dienst gab der Fehlerverarbeiter eine Schnittstelle mit einem nil-Wert zurück, und die Clients betrachteten den Fehler als nicht null, was zu überflüssigen Aktionen führte. Das Problem lag im Vergleich der Schnittstelle mit nil.
Geschichte
Beschreibung: Bei der Erstellung von Tests wurde fälschlicherweise der Fehler des Schnittstellentyps auf Gleichheit mit nil überprüft, nachdem eine Struktur mit nil-Feldern zurückgegeben wurde. Die Tests erkannten die echten Fehler nicht, was zu einem Bug in der Produktion führte.
Geschichte
Beschreibung: Bei der Migration von einem Schnittstellentyp zu einem anderen wurde vergessen, alle Methoden der neuen Schnittstelle zu implementieren, da es kein explizites implements gab. Der Code wurde kompiliert, aber die Schnittstelle wurde nicht implementiert, einige Mock-Funktionen hörten auf zu funktionieren.