In Go ist ein Zeiger eine Variable, die die Adresse einer anderen Variable speichert. Im Gegensatz zu einigen Sprachen ist es in Go nicht möglich, Zeigerarithmetik durchzuführen, was sie sicherer macht. Zeiger werden in Go häufig verwendet für:
In Go fehlt die explizite Unterstützung für Referenztypen, wie zum Beispiel in C++, jedoch sind Slices und Maps aufgrund ihrer Natur bereits referenziell und werden oft per Wert übergeben.
package main import "fmt" type User struct { Name string } func changeNameByValue(u User) { u.Name = "Vasya" } func changeNameByPointer(u *User) { u.Name = "Petya" } func main() { user := User{Name: "Ivan"} changeNameByValue(user) fmt.Println(user.Name) // Ivan changeNameByPointer(&user) fmt.Println(user.Name) // Petya }
Können Zeiger in Go auf Konstanten oder Literale zeigen?
Korrekte Antwort: Nein, in Go kann man nicht direkt eine Adresse von einer Konstante oder einem Literal nehmen. Eine Adresse kann nur von einer Variablen genommen werden:
x := 5 p := &x // OK p2 := &10 // Kompilierungsfehler
Dies führt oft zu Verwirrungen mit Sprachen, in denen dies zulässig ist.
Geschichte
In einem Projekt versuchte ein Entwickler, einen Verweis auf ein Element eines Slices zu übergeben, in der Annahme, dass er das Slice sicher über den Zeiger modifizieren könnte. Er irrte sich: Das Slice selbst enthält einen Zeiger, aber nach append() ändert sich die Adresse des zugrunde liegenden Arrays und die Änderungen spiegelten sich nicht immer in den Originaldaten wider. Dies führte zu schwer fassbaren Bugs (Daten "gingen verloren").
Geschichte
In dem Projekt wurde eine Liste von Zeigern auf lokale Variablen in einer Schleife erstellt, und nach Verlassen der Schleife zeigten alle Zeiger auf dieselbe Variable (die durchlaufene Schleifenvariable). Der Fehler wurde erst nach einem Absturz in der Produktion bemerkt.
Geschichte
Der Entwickler ging fälschlicherweise davon aus, dass die Zuweisung eines Zeigers das vorherige Objekt aus dem Speicher freigibt und wies den Zeiger ausdrücklich auf nil zu, in der Erwartung, dass der GC sofort reagiert. In der Praxis entscheidet der Garbage Collector in Go selbst, wann Objekte bereinigt werden, dabei ignoriert er vorzeitige Nullsetzungen von Referenzen. Dies führte zu Speicherlecks, wo man mit einer zeitgerechten Freigabe des Speichers rechnete.