Heim >Backend-Entwicklung >Golang >Warum erfüllt mein generischer Go-Typparameter nicht die „Stringer'-Schnittstelle?

Warum erfüllt mein generischer Go-Typparameter nicht die „Stringer'-Schnittstelle?

Susan Sarandon
Susan SarandonOriginal
2024-12-25 11:10:13482Durchsuche

Why Doesn't My Go Generic Type Parameter Satisfy the `stringer` Interface?

Generische Typeinschränkungen in Go verstehen

In Go 1.18 bieten Generika ein leistungsstarkes Werkzeug zur Verbesserung der Codeflexibilität. Beim Arbeiten mit Typeinschränkungen ist es jedoch wichtig zu verstehen, warum bestimmte Fehler auftreten können.

Das Problem

Berücksichtigen Sie den folgenden Code:

type stringer interface {
    a() string
}

func do(s stringer) {
    fmt.Println(s.a())
}

func blah[T FooBar]() {
    t := &T{}
    do(t)
}

func main() {
    blah[foo]()
}

Beim Kompilierungsversuch Wenn Sie diesen Code verwenden, tritt möglicherweise der Fehler auf:

cannot use t (variable of type *T) as type stringer in argument to do: *T does not implement stringer (type *T is pointer to type parameter, not type parameter)

Den Fehler verstehen

Dieser Fehler beruht auf einem Missverständnis darüber, wie generische Typbeschränkungen funktionieren. Die Einschränkung FooBar in der Blah-Funktion ist ein Platzhalter für Typen, die die Schnittstelle FooBar erfüllen. Die Variable t ist jedoch vom Typ T, was ein Zeiger auf den Typparameter T ist. Dies bedeutet, dass T selbst kein Typparameter ist und daher die Stringer-Schnittstelle nicht erfüllen kann.

Die Lösung

Die Lösung für dieses Problem besteht darin, eine Beziehung zwischen dem Typparameter T und der Stringer-Schnittstelle einzuführen. Es gibt zwei mögliche Ansätze:

1. Explizite Behauptung

Sie können mithilfe der Any-Type-Konvertierung explizit behaupten, dass *T die Stringer-Schnittstelle erfüllt:

func blah[T FooBar]() {
    t := &T{}
    do(any(t).(stringer))
}

2. Typzusammensetzung

Alternativ können Sie einen neuen Typ definieren, der die Einschränkungen von FooBar und Stringer kombiniert:

type FooBar[T foo | bar] interface {
    *T
    stringer
}

func blah[T foo | bar, U FooBar[T]]() {
    var t T
    do(U(&t))
}

Dieser Ansatz gewährleistet die Typsicherheit durch Einbetten von Stringer in die FooBar-Schnittstelle und erfordert, dass T ein Zeigertyp ist, um die Einschränkung zu erfüllen FooBar.

Fazit

Das Verständnis der Beziehung zwischen Typbeschränkungen und Typparametern ist entscheidend für die effektive Arbeit mit Generika in Go. Durch die Einführung einer Beziehung zwischen T und Stringer, entweder durch explizite Behauptung oder Typkomposition, können Sie den Fehler beheben und das gewünschte Verhalten aktivieren.

Das obige ist der detaillierte Inhalt vonWarum erfüllt mein generischer Go-Typparameter nicht die „Stringer'-Schnittstelle?. 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