Ich weiß, dass Zeiger in Go die Mutation der Argumente einer Funktion ermöglichen, aber wäre es nicht einfacher gewesen, wenn sie nur Referenzen (mit geeigneten const- oder veränderlichen Qualifikationsmerkmalen) übernommen hätten. Jetzt haben wir Zeiger und für einige eingebaute Typen wie Karten und Kanäle wird implizit als Referenz übergeben.
Vermisse ich etwas oder sind Zeiger in Go nur eine unnötige Komplikation?
Antworten:
Ich mag ein Beispiel aus http://www.golang-book.com/8
im Gegensatz zu
quelle
Zeiger sind aus mehreren Gründen nützlich. Zeiger ermöglichen die Kontrolle über das Speicherlayout (wirkt sich auf die Effizienz des CPU-Cache aus). In Go können wir eine Struktur definieren, in der sich alle Mitglieder im zusammenhängenden Speicher befinden:
In diesem Fall sind die
Point
Strukturen in die Struktur eingebettetLineSegment
. Sie können Daten jedoch nicht immer direkt einbetten. Wenn Sie Strukturen wie Binärbäume oder verknüpfte Listen unterstützen möchten, müssen Sie eine Art Zeiger unterstützen.Java, Python usw. haben dieses Problem nicht, da Sie keine zusammengesetzten Typen einbetten können, sodass syntaktisch nicht zwischen Einbetten und Zeigen unterschieden werden muss.
Probleme mit Swift / C # -Strukturen, die mit Go-Zeigern behoben wurden
Eine mögliche Alternative, um dasselbe zu erreichen, besteht darin, zwischen
struct
undclass
wie C # und Swift zu unterscheiden. Dies hat jedoch Einschränkungen. Während Sie normalerweise angeben können, dass eine Funktion eine Struktur alsinout
Parameter verwendet, um das Kopieren der Struktur zu vermeiden, können Sie keine Verweise (Zeiger) auf Strukturen speichern. Dies bedeutet, dass Sie eine Struktur niemals als Referenztyp behandeln können, wenn Sie dies nützlich finden, z. B. um einen Pool-Allokator zu erstellen (siehe unten).Benutzerdefinierter Speicherzuweiser
Mithilfe von Zeigern können Sie auch Ihren eigenen Pool-Allokator erstellen (dies ist sehr vereinfacht, da viele Überprüfungen entfernt wurden, um nur das Prinzip zu zeigen):
Tauschen Sie zwei Werte aus
Mit Zeigern können Sie auch implementieren
swap
. Das heißt, die Werte zweier Variablen werden ausgetauscht:Fazit
Java war nie in der Lage, C ++ für die Systemprogrammierung an Orten wie Google vollständig zu ersetzen, auch weil die Leistung nicht in gleichem Maße angepasst werden kann, da das Speicherlayout und die Speicherauslastung nicht gesteuert werden können (Cache-Fehler beeinträchtigen die Leistung erheblich). Go hat sich zum Ziel gesetzt, C ++ in vielen Bereichen zu ersetzen und muss daher Zeiger unterstützen.
quelle
Referenzen können nicht neu zugewiesen werden, Zeiger dagegen. Dies allein macht Zeiger in vielen Situationen nützlich, in denen Referenzen nicht verwendet werden konnten.
quelle
Go ist als knappe, minimalistische Sprache konzipiert. Es begann daher nur mit Werten und Zeigern. Später wurden notwendigerweise einige Referenztypen (Slices, Karten und Kanäle) hinzugefügt.
Die Go-Programmiersprache: Sprachdesign FAQ: Warum verweisen Karten, Slices und Kanäle, während Arrays Werte sind?
"Es gibt viel Geschichte zu diesem Thema. Schon früh waren Karten und Kanäle syntaktisch Zeiger und es war unmöglich, eine Nicht-Zeiger-Instanz zu deklarieren oder zu verwenden. Außerdem hatten wir Probleme damit, wie Arrays funktionieren sollten. Schließlich entschieden wir uns für die strikte Trennung Durch die Einführung von Referenztypen, einschließlich Slices zur Behandlung der Referenzform von Arrays, wurden diese Probleme behoben. Referenztypen fügten der Sprache eine bedauerliche Komplexität hinzu, haben jedoch einen großen Einfluss auf die Benutzerfreundlichkeit: Go wurde zu einem produktivere, bequemere Sprache, als sie eingeführt wurden. "
Schnelle Kompilierung ist ein wichtiges Designziel der Programmiersprache Go. das hat seine kosten. Eines der Opfer scheint die Fähigkeit zu sein, Variablen (mit Ausnahme grundlegender Kompilierungszeitkonstanten) und Parameter als unveränderlich zu markieren. Es wurde angefordert, aber abgelehnt.
Golang-Nüsse: Geh Sprache. Einige Rückmeldungen und Zweifel.
"Das Hinzufügen von const zum Typsystem erzwingt, dass es überall angezeigt wird, und zwingt einen, es überall zu entfernen, wenn sich etwas ändert. Das Markieren von Objekten, die auf irgendeine Weise unveränderlich sind, kann zwar von Vorteil sein, wir glauben jedoch nicht, dass ein const-Typ-Qualifizierer zu weit entfernt ist gehen."
quelle