In Go, un puntatore è una variabile che memorizza l'indirizzo di un'altra variabile. A differenza di alcuni linguaggi, in Go non è possibile eseguire l'aritmetica dei puntatori, il che li rende più sicuri. I puntatori in Go vengono spesso utilizzati per:
In Go non esiste un supporto esplicito per i tipi di riferimento, come in C++, tuttavia gli slices e le maps sono già di natura referenziale e vengono spesso passati per valore.
package main import "fmt" type User struct { Name string } func changeNameByValue(u User) { u.Name = "Vasja" } func changeNameByPointer(u *User) { u.Name = "Petja" } func main() { user := User{Name: "Ivan"} changeNameByValue(user) fmt.Println(user.Name) // Ivan changeNameByPointer(&user) fmt.Println(user.Name) // Petja }
Possono i puntatori puntare a costanti o letterali in Go?
Risposta corretta: No, in Go non è possibile ottenere l'indirizzo di una costante o di letterali direttamente. L'indirizzo può essere preso solo da una variabile:
x := 5 p := &x // OK p2 := &10 // Errore di compilazione
Questo è spesso confuso con i linguaggi in cui ciò è consentito.
Storia
In un progetto, uno sviluppatore ha cercato di passare un riferimento a un elemento di uno slice, pensando di poter modificare in sicurezza lo slice tramite un puntatore. Ma si è sbagliato: lo slice contiene un puntatore, ma dopo append() l'indirizzo dell'array sottostante cambia, e le modifiche non si riflettono sempre sui dati originali. Questo ha portato a bug difficili da rilevare (i dati venivano "persi").
Storia
In un progetto è stata creata una lista di puntatori a variabili locali in un ciclo, e dopo l'uscita dal ciclo tutti i puntatori puntavano alla stessa variabile (la variabile iterata del ciclo). L'errore è stato notato solo dopo un crash in produzione.
Storia
Uno sviluppatore ha erroneamente pensato che l'assegnazione di un puntatore liberasse l'oggetto precedente dalla memoria, e ha assegnato esplicitamente il puntatore a nil, aspettandosi la GC immediatamente. Nella pratica, in Go il garbage collector decide quando pulire gli oggetti, ignorando l'azzeramento prematuro dei riferimenti. Questo ha portato a perdite di memoria dove si sperava in un rilascio tempestivo della memoria.