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?

Warum gibt Go einen Fehler aus, wenn eine konkrete Typimplementierung einen konkreten Typ anstelle des erwarteten Schnittstellentyps in einer Schnittstellenmethode zurückgibt?

DDD
DDDOriginal
2024-10-30 07:33:02189Durchsuche

Why does Go throw an error when a concrete type implementation returns a concrete type instead of the expected interface type in an interface method?

Schnittstellenmethode, die Schnittstellenkonflikt mit konkreter Typimplementierung 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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn