Skip to content
Pointers in Go
step 1/7

Reading — step 1 of 7

Learn

~3 min readPointers and Errors

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 *

go
  • &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:

go

Pointers to structs

For structs, Go automatically dereferences for field access:

go

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

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:

go

In practice you use &Type{...} more often:

go

What Go DOESN'T have

Unlike C and C++:

  • No pointer arithmeticp + 1 is 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* — use interface{} (or any in 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…