Reading — step 1 of 7
Learn
Go has pointers — but a much simpler model than C or C++. No pointer arithmetic, no manual delete, no dangling pointers (the GC and escape analysis prevent that). What you DO need to understand: when does Go pass by value vs reference, and when do you reach for & and *.
The basics — & and *
&value— take the address; produces a pointer.*pointer— dereference; access the value it points at.*Type— pointer-to-Type (a TYPE, e.g.,*int,*User).
Pointers as function parameters
Go passes everything by VALUE. To let a function modify the caller's variable, pass a pointer:
Pointers to structs
For structs, Go automatically dereferences for field access:
You'll see the third form everywhere — Go's syntactic sugar.
When to use pointers
Use pointers when:
- The function needs to MUTATE the caller's value
- The struct is large and you want to avoid copying it
- You want to indicate "may be missing" (nil pointer)
- You're working with a large slice/map/channel field that's expensive to copy
Use values when:
- The struct is small (few fields, all primitives)
- The function is read-only and doesn't modify state
- You want to make accidental aliasing impossible
Idiomatic Go uses pointers for most struct types — see the standard library.
nil pointers — the panic
Go doesn't have null safety like Kotlin or Swift. Dereferencing nil pointers panics at runtime. Always check or use the zero-value pattern.
Allocating with new
new(T) returns a *T pointing at a zeroed value:
In practice you use &Type{...} more often:
What Go DOESN'T have
Unlike C and C++:
- No pointer arithmetic —
p + 1is a compile error. - No manual delete — the GC handles freeing.
- No dangling pointers — escape analysis moves stack values to the heap if their address escapes the function.
- No
void*— useinterface{}(oranyin Go 1.18+).
Common mistakes
- Dereferencing a nil pointer — runtime panic. Always check or guarantee non-nil.
- Returning a pointer to a local you intended to be temporary — Go allocates it on the heap automatically (escape analysis), so it doesn't dangle, but performance-wise you might prefer returning by value.
- Forgetting
&when calling a pointer-receiver method — Go auto-takes-address for ADDRESSABLE values (named variables) but not for literals.methodOnPointer(MyType{...})may fail.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…