Heim  >  Artikel  >  Backend-Entwicklung  >  Warum unterstützt Golang 1.18 Generics die Kovarianz nicht vollständig?

Warum unterstützt Golang 1.18 Generics die Kovarianz nicht vollständig?

Susan Sarandon
Susan SarandonOriginal
2024-11-17 18:06:02128Durchsuche

Why Doesn't Golang 1.18 Generics Fully Support Covariance?

Kovarianz in Golang 1.18-Generika: Ihre Einschränkungen verstehen

Die Einführung von Generika in Golang 1.18 brachte viele Fortschritte mit sich, aber bestimmte Einschränkungen bleiben bestehen, einschließlich das Fehlen einer vollständigen Kovarianzunterstützung.

Das Problem verstehen

Stellen Sie sich ein Szenario vor, in dem Sie eine generische Funktion namens Pipe definieren möchten, die zwei Funktionen annimmt:

  • links: Akzeptiert ein Argument vom Typ A und gibt einen Wert vom Typ T1 zurück.
  • rechts: Akzeptiert ein Argument vom Typ T1 und gibt einen Wert vom Typ T2 zurück.

Das Ziel besteht darin, eine Funktion zu erstellen, die die Ausgabe von links als Eingabe für rechts ausführt. Die folgende Implementierung kann jedoch in einigen Fällen nicht kompiliert werden:

func Pipe[A, T1, T2 any](left func(A) T1, right func(T1) T2) func(A) T2 {
    return func(a A) T2 {
        return right(left(a))
    }
}

Dieses Problem tritt auf, weil Golang-Generika die Kovarianz nicht vollständig unterstützen. Kovarianz bedeutet, dass ein Typparameter durch einen Subtyp ersetzt werden kann, ohne den Vertrag zu verletzen. In diesem Fall lässt T1 keine Untertypen zu, während io.ReadCloser ein Untertyp von io.Reader ist.

Golangs Designentscheidung

Golangs Entscheidung, Kovarianz nicht vollständig zu implementieren basiert auf Sicherheitsüberlegungen. Das Zulassen von Kovarianz könnte zu Situationen führen, in denen Funktionen mit Typen aufgerufen werden, die nicht mit ihren beabsichtigten Signaturen übereinstimmen, was zu undefiniertem Verhalten führt.

FAQ-Erklärungen

In den Golang-FAQ heißt es ausdrücklich dass das aktuelle Verhalten beabsichtigt und kein Fehler ist. Diese Entscheidung zielt darauf ab, unerwartete Laufzeitfehler zu verhindern, die die Anwendungszuverlässigkeit beeinträchtigen könnten.

Konvertierbare Typen im Vergleich zu kovarianten Typen

Golang unterstützt zwar keine vollständige Kovarianz, ermöglicht jedoch die Umwandlung eines Typs in einen anderen. Im Fall von func Pipe gibt es jedoch keine Möglichkeit, diese Konvertierung mithilfe von Typparametern darzustellen.

Alternativ können Sie das Ergebnis von left explizit in den von right benötigten Typ umwandeln. Allerdings ist dieser Ansatz zur Kompilierungszeit nicht typsicher, wie im folgenden geänderten Code gezeigt:

func Pipe[A, T1, T2, T3 any](left func(A) T1, right func(T2) T3) func(A) T3 {
    return func(a A) T3 {
        return right(any(left(a)).(T2))
    }
}

Während dies die Aufgabe erledigt, opfert es die Sicherheit zur Kompilierungszeit für die Laufzeitkonvertierung.

Das obige ist der detaillierte Inhalt vonWarum unterstützt Golang 1.18 Generics die Kovarianz nicht vollständig?. 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