Pointers
Pointers in Go — the `&` and `*` operators, value vs reference semantics, the nil pointer, and when a pointer is actually needed.
6 questions
JuniorTheoryVery commonWhat does the program print?
What does the program print?
1 20 30
Open full question →Common mistakes
- ✗Expecting
10 20 30: Go passes every argument by value, sonis a copy ofa, and writing to it leavesaat 1. - ✗Expecting
1 20 3: the slice header is copied, but the copy points to the same array, sos[0] = 30is seen inmain.
Follow-up questions
- →Why does appending to a slice inside a function sometimes not show up outside?
- →How does a pointer receiver method differ from a value receiver here?
JuniorTheoryCommonWhat do the & and * operators do with pointers in Go?
What do the & and * operators do with pointers in Go?
&x takes the address of x and yields a pointer of type *T. *p dereferences a pointer to read or write the value it points at. A pointer's zero value is nil, meaning it points at nothing yet. Go has no pointer arithmetic — you cannot add to or subtract from a pointer the way C allows.
Common mistakes
- ✗Swapping the operators — thinking
&dereferences and*takes an address - ✗Expecting C-style pointer arithmetic to work on a Go pointer
- ✗Forgetting that a pointer's zero value is
nil, not address zero
Follow-up questions
- →What is the difference between
*Tin a type and*pin an expression? - →Why does Go deliberately leave out pointer arithmetic?
JuniorTheoryCommonWhat does the program print?
What does the program print?
5 1
Open full question →Common mistakes
- ✗Expecting
xto stay1:p := &xstores the address ofx, not a copy, so*p = 5writes intoxitself. - ✗Expecting
yto followx:y := *pcopies the value1thatppoints to at that moment, soystays1.
Follow-up questions
- →What would the program print if the line were
p = &yinstead ofy := *p? - →What is the type of
p, and why can it not hold the address of astring?
JuniorTheoryCommonWhat happens when this program is built and run?
What happens when this program is built and run?
Panic: runtime error: invalid memory address or nil pointer dereference
Open full question →Common mistakes
- ✗Expecting
0, as when reading a missing key from a map:*preads theintat the address inp, and anilpointer has nointbehind it, so the program panics. - ✗Expecting
<nil>: that is whatfmt.Println(p)would print;*pasks for the value behind the pointer, not the pointer itself.
Follow-up questions
- →How would you change the program so that it prints
0without a panic? - →How can a function guard against being handed a
nilpointer?
JuniorTheoryCommonWhat happens when you dereference a nil pointer in Go?
What happens when you dereference a nil pointer in Go?
Dereferencing a nil pointer triggers a runtime panic: invalid memory address or nil pointer dereference. nil is the zero value of any pointer, so an unassigned pointer holds nil until you point it somewhere. Guard with if p != nil before reading *p, or recover the panic at a boundary. There is no silent null read like C might give.
Common mistakes
- ✗Expecting a silent zero-value read instead of a panic
- ✗Thinking the nil dereference is caught at compile time
- ✗Skipping the
if p != nilguard before reading*p
Follow-up questions
- →How can
recoverturn a nil-pointer panic into a handled error? - →Why can a nil pointer of a concrete type sit inside a non-nil interface?
MiddleTheoryCommonWhen should a function take a pointer rather than a value in Go?
When should a function take a pointer rather than a value in Go?
Take a *T when the function must mutate the caller's value, or to avoid copying a large struct on every call. Prefer a value for small immutable data — it keeps the API copy-safe, so the callee cannot alter the caller's state. Passing a pointer also lets the callee observe nil to mean "absent", which a value parameter can never express.
Common mistakes
- ✗Defaulting to pointers everywhere and losing the copy-safety of value parameters
- ✗Believing a value parameter can mutate the caller without a pointer
- ✗Overlooking that only a pointer parameter can carry
nilfor "absent"
Follow-up questions
- →How does this guidance map onto choosing a value vs pointer method receiver?
- →At what struct size does copy cost actually start to matter in practice?