Go-Zeiger: Ein genauerer Blick auf Werte und Zeigerempfänger
In Go spielen Zeiger eine entscheidende Rolle bei der effektiven Speicherverwaltung und der Erstellung von Wiederverwendbarkeiten Datenstrukturen. Anfänger haben oft mit dem Konzept der Zeiger zu kämpfen, insbesondere weil es sich von Sprachen wie C/C unterscheidet. Ziel dieses Artikels ist es, die Nuancen von Go-Zeigern zu klären und häufige Missverständnisse auszuräumen.
Betrachten Sie den folgenden Codeausschnitt, der der Go-Tour Nr. 52 entlehnt ist:
type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func main() { v := &Vertex{3, 4} fmt.Println(v.Abs()) }
Hier definieren wir eine Struktur Vertex und eine Methode Abs, die den Absolutwert eines Vertex berechnet. Der Empfänger v von Abs ist ein Zeiger auf Vertex. Dies bedeutet, dass Abs mit Zeigern auf Scheitelpunkte arbeitet und Änderungen am ursprünglichen Scheitelpunkt ermöglicht.
Betrachten wir nun eine geringfügige Änderung des Codes:
func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) }
Interessanterweise führt diese Änderung zu das gleiche Ergebnis. Es stellt sich unsere Frage: Gibt es einen Unterschied zwischen der Verwendung eines *Vertex oder eines Vertex als Empfänger für Abs?
Die Antwort liegt in zwei Grundregeln von Go:
Konvertierung von Werten und Zeigerempfängern: Go ermöglicht die Ableitung einer Methode mit einem Zeigerempfänger von einer Methode mit einem Wertempfänger. Somit generiert func (v Vertex) Abs() float64 automatisch eine zusätzliche Implementierung:
func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) } func (v *Vertex) Abs() float64 { return Vertex.Abs(*v) } // GENERATED METHOD
Der Compiler findet die generierte Methode nahtlos und erklärt, warum v.Abs() immer noch funktioniert, obwohl v kein Zeiger ist .
Automatische Adresserfassung: Go kann die Adresse einer Variablen automatisch übernehmen. Das heißt, wenn v.Abs() im geänderten Code ohne den Zeigerempfänger aufgerufen wird, ist es äquivalent zu:
vp := &v vp.Abs()
Somit erhält die Funktion immer noch einen Zeiger auf den Scheitelpunkt, unabhängig davon, ob wir explizit & verwenden .
Das obige ist der detaillierte Inhalt vonGo-Zeiger: Wert vs. Zeigerempfänger – Ist das wichtig?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!