Haftungsausschluss: Ich habe jetzt nur einen Tag mit Go gespielt, daher besteht eine gute Chance, dass ich viel verpasst habe.
Weiß jemand, warum es in Go keine echte Unterstützung für Generika / Vorlagen / whatsInAName gibt? Es gibt also ein generisches map
Programm, das jedoch vom Compiler bereitgestellt wird, während ein Go-Programmierer keine eigene Implementierung schreiben kann. Warum kann ich bei all dem Gerede darüber, Go so orthogonal wie möglich zu gestalten, einen generischen Typ verwenden, aber keinen neuen erstellen?
Besonders wenn es um funktionale Programmierung geht, gibt es Lambdas, sogar Schließungen, aber mit einem statischen Typsystem ohne Generika, wie schreibe ich generische Funktionen höherer Ordnung wie filter(predicate, list)
? OK, verknüpfte Listen und dergleichen können unter interface{}
Einbußen bei der Typensicherheit durchgeführt werden.
Da eine schnelle Suche in SO / Google keine Erkenntnisse ergab, sieht es so aus, als würden Generika, wenn überhaupt, nachträglich zu Go hinzugefügt. Ich vertraue darauf, dass Thompson es viel besser macht als die Java-Leute, aber warum sollten Generika draußen bleiben? Oder sind sie geplant und noch nicht umgesetzt?
interface{}
opfert statische Sicherheit. Dies ist jedoch eine etwas seltsame Beschwerde, wenn das Erwähnen von Schema der nächste Absatz ist, da Schema normalerweise keine statische Typprüfung aufweist.Antworten:
Diese Antwort finden Sie hier: http://golang.org/doc/faq#generics
quelle
interface{}
, ist der grundlegendste Schnittstellentyp, und jedes Objekt stellt ihn bereit. Wenn Sie einen Container erstellen, der sie enthält, kann er jedes (nicht primitive) Objekt akzeptieren. Es ist also einem ContainerObjects
in Java sehr ähnlich .Gehe 2
Unter https://blog.golang.org/go2draft finden Sie einen Entwurf für Generika .
Gehen Sie 1
Russ Cox, einer der Go-Veteranen, schrieb einen Blog-Beitrag mit dem Titel The Generic Dilemma , in dem er fragt
Langsame Programmierer sind das Ergebnis von keinen Generika. Langsame Compiler werden wie Generika durch C ++ verursacht. Langsame Ausführungszeiten ergeben sich aus dem von Java verwendeten Boxing-Unboxing-Ansatz.
Die vierte Möglichkeit, die im Blog nicht erwähnt wird, ist die C # -Route. Generieren des speziellen Codes wie in C ++, jedoch zur Laufzeit, wenn dies erforderlich ist. Ich mag es wirklich, aber Go ist ganz anders als C #, also ist dies wahrscheinlich überhaupt nicht anwendbar ...
Ich sollte erwähnen, dass die Verwendung der beliebten Java 1.4-ähnlichen Technik der generischen Programmierung in go , bei der Casts verwendet
interface{}
werden, neben dem Verlust der Sicherheit des Kompilierungszeittyps genau dieselben Probleme wie das Boxen-Entpacken aufweist (weil wir dies tun). Für kleine Typen (wie Ints) optimiert Go deninterface{}
Typ so, dass eine Liste von Ints, die in die Schnittstelle {} umgewandelt wurden, einen zusammenhängenden Speicherbereich belegt und nur doppelt so viel Speicherplatz benötigt wie normale Ints. Es gibt jedoch immer noch den Aufwand für Laufzeitprüfungen beim Casting voninterface{}
. Referenz .Alle Projekte, die generische Unterstützung hinzufügen (es gibt mehrere davon und alle sind interessant), gehen einheitlich den C ++ - Weg der Generierung von Kompilierungszeitcode.
quelle
[]interface{}
, 2x den RAM als verwenden[]int
. Während dies zutrifft, verwenden auch kleinere Typen (dh Bytes) bis zum 16-fachen des Arbeitsspeichers[]byte
.Obwohl Generika derzeit nicht integriert sind, gibt es mehrere externe Implementierungen von Generika für unterwegs, die Kommentare in Kombination mit kleinen Dienstprogrammen verwenden, die Code generieren.
Hier ist eine solche Implementierung: http://clipperhouse.github.io/gen/
quelle
Eigentlich laut diesem Beitrag:
quelle
Parametrischer Polymorphismus (Generika) wird für Go 2 in Betracht gezogen .
Dieser Ansatz würde das Konzept eines Vertrags einführen, mit dem Einschränkungen für Typparameter ausgedrückt werden können:
Ein solcher Vertrag könnte dann folgendermaßen genutzt werden:
Dies ist ein Vorschlag in dieser Phase.
Ihre
filter(predicate, list)
Funktion könnte mit einem Typparameter wie dem folgenden implementiert werden:In diesem Fall besteht keine Notwendigkeit zur Einschränkung
T
.quelle