Heim > Artikel > Backend-Entwicklung > Warum unterstützt Golang 1.18 Generics die Kovarianz nicht vollständig?
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:
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!