Pointers in Go
By Flavio Copes
Learn how pointers work in Go, using & to get a variable memory address and * to read its value, so you can change the original inside a function.
A pointer in Go holds the memory address of a value. You get the address of a variable with the & operator, and you read the value stored at that address with the * operator.
Suppose you have a variable:
age := 20
Using &age you get the pointer to the variable, its memory address. Its type is *int, “pointer to an int”.
When you have the pointer to the variable, you can get the value it points to by using the * operator:
age := 20
ageptr := &age
agevalue := *ageptr //20
Printing a pointer shows the address itself, which changes on every run:
fmt.Println(ageptr) //0xc000012028
fmt.Println(*ageptr) //20
Why do we need pointers?
This is useful when you want to call a function and pass the variable as a parameter. Go by default copies the value of the variable inside the function, so this will not change the value of age:
func increment(a int) {
a = a + 1
}
func main() {
age := 20
increment(age)
//age is still 20
}
The function got its own copy, incremented that, and threw it away.
You can use pointers for this:
func increment(a *int) {
*a = *a + 1
}
func main() {
age := 20
increment(&age)
//age is now 21
}
Now increment() receives a *int. Writing to *a writes through the pointer, straight into the memory where age lives. So the change survives after the function returns.
This is also why some methods use pointer receivers: they need to modify the struct they’re called on, not a copy of it.
Watch out for nil pointers
The zero value of a pointer is nil. A declared but unassigned pointer points at nothing, and dereferencing it crashes the program:
var score *int
fmt.Println(*score)
This panics with:
panic: runtime error: invalid memory address or nil pointer dereference
The fix is making sure the pointer points at something before you use *:
var score *int
points := 42
score = &points
fmt.Println(*score) //42
One last thing. Unlike C, Go pointers have no arithmetic. You can’t add 1 to a pointer to walk through memory. A pointer either references a valid value or is nil, and that removes a whole class of bugs.