Heim > Artikel > Backend-Entwicklung > Warum gibt Go einen Fehler aus, wenn eine konkrete Typimplementierung einen konkreten Typ anstelle des erwarteten Schnittstellentyps in einer Schnittstellenmethode zurückgibt?
Beim Arbeiten mit Go-Schnittstellen kann ein Fehler auftreten, wenn eine Schnittstellenmethode implementiert wird, die einen Rückgabetyp der Schnittstelle deklariert nach einem konkreten Typ. Dieser Fehler tritt auf, weil die Implementierung der Methode nicht direkt den Schnittstellentyp zurückgibt, sondern stattdessen einen konkreten Typ, der die Schnittstelle implementiert.
Betrachten Sie das folgende Beispiel:
<code class="go">package main import "fmt" type Foo struct { val string } func (f *Foo) String() string { return f.val } type StringerGetter interface { GetStringer() fmt.Stringer } type Bar struct{} func (b *Bar) GetStringer() *Foo { return &Foo{"foo"} } func Printer(s StringerGetter) { fmt.Println(s.GetStringer()) } func main() { f := Bar{} Printer(&f) }</code>
Hier die Die Druckerfunktion erwartet eine StringerGetter-Schnittstelle, die über eine GetStringer-Methode verfügt, die einen fmt.Stringer zurückgibt, während die GetStringer-Methode des Bar-Typs einen konkreten Typ Foo zurückgibt, der die fmt.Stringer-Schnittstelle implementiert. Dies verursacht den Fehler:
prog.go:29: cannot use &f (type *Bar) as type StringerGetter in argument to Printer: *Bar does not implement StringerGetter (wrong type for GetStringer method) had GetStringer() *Foo want GetStringer() fmt.Stringer
Die Lösung für dieses Problem besteht darin, die Methoden der Schnittstelle an die erwarteten Schnittstellentypen anzupassen. In diesem Fall sollte die GetStringer-Methode fmt.Stringer anstelle eines konkreten Typs zurückgeben:
<code class="go">func (b *Bar) GetStringer() fmt.Stringer { return &Foo{"foo"} }</code>
Alternativ kann man einen Wrapper-Typ erstellen, der die gewünschte Schnittstelle implementiert und an den konkreten Typ delegiert, wie in gezeigt die folgenden Techniken:
Typeinbettung mit Delegation:
<code class="go">type MyBar struct{ Bar } func (b *MyBar) GetStringer() fmt.Stringer { return b.Bar.GetStringer() }</code>
Typumbruch:
<code class="go">type MyBar Bar func (b *MyBar) GetStringer() fmt.Stringer { return &Foo{"foo"} }</code>
Diese Techniken ermöglichen eine nahtlose Anbindung an Betontypen, ohne diese direkt zu ändern. Durch Umhüllen oder Einbetten der konkreten Typen können benutzerdefinierte Typen erstellt werden, die den gewünschten Schnittstellenverträgen entsprechen.
Das obige ist der detaillierte Inhalt vonWarum gibt Go einen Fehler aus, wenn eine konkrete Typimplementierung einen konkreten Typ anstelle des erwarteten Schnittstellentyps in einer Schnittstellenmethode zurückgibt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!