Types you define · 3 MIN READ
A pointer is for changing something, not for speed
Say when a pointer is required and when it is only noise.
Go passes everything by value. A struct handed to a function is copied, and writing to the copy changes nothing the caller can see. A pointer is how you say "the same one", and & and * are the whole syntax: &value takes an address, *pointer reads through one. Field access needs no * — p.X works on a pointer as well as a value, which is why you rarely see the star in ordinary code.
There is no pointer arithmetic. A Go pointer either points at something or is nil, and that is all it can do — which is why passing one is safe in a way it is not in C.
The reason to use one is mutation. "Pointers are faster" is a guess: for a small struct the copy is often cheaper than the indirection and the extra work the garbage collector inherits. Measure before believing it, and until you have, choose based on whether the callee needs to change what it was given.
SEE THE IDEA
Two names can reach one value
- 01
One value
gocount := 4The storage being referred to
- 02
First pointer
gop := &countRefers to count
- 03
Second pointer
goq := pRefers to that same count
Assigning through either pointer changes the one shared value.
In practice
Use a pointer to communicate shared identity or a permitted mutation. A pointer is itself copied when passed to a function, so reassigning the parameter changes only that local pointer; assigning through it changes the pointed-to value. Check nil before dereferencing an optional pointer.
Watch out
A pointer does not automatically make code faster. Allocation and copying behavior depend on the program and compiler.
Read and predict
package main
import "fmt"
type Settings struct {
Retries int
}
func byValue(s Settings) {
s.Retries = 9
}
func byPointer(s *Settings) {
s.Retries = 9
}
func main() {
s := Settings{Retries: 1}
byValue(s)
fmt.Println(s.Retries)
byPointer(&s)
fmt.Println(s.Retries)
}What are the two numbers, and why are they different?
Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.
Progress stays in this browser. No account needed.