Reading — step 1 of 6
Learn
Methods in Go attach to a type via a receiver. The receiver can be a value or a pointer — and choosing wrong is one of Go's classic gotchas.
The two forms
(c Counter) is the value-receiver form. The method gets a copy of the struct. Mutations don't persist.
(c *Counter) is the pointer-receiver form. The method gets a pointer — mutations go through to the original.
Why this matters
Go automatically takes the address when you call a pointer-receiver method on an addressable value.
When to use a pointer receiver
Use *T when:
- The method needs to mutate the receiver — value receivers can't.
- The struct is large — copying is expensive.
- For consistency — if any method on the type uses a pointer receiver, all of them should.
Use value receiver when:
- The type is small (an int, a small struct).
- You don't need to mutate.
- The type is meant to be a value type (Time, Color, Coordinate).
The map element trap
Map values aren't addressable — you can't get a pointer to them, so you can't call pointer-receiver methods on them directly.
Interface satisfaction
Value and pointer methods determine which type satisfies an interface:
If Greet had a pointer receiver, only *Dog (not Dog) would satisfy the interface.
Common mistakes
- Calling a pointer method on a non-addressable value: e.g.,
someFunc().Method()wheresomeFunc()returns a value, not a pointer. - Mixing value and pointer receivers on the same type — confusing for readers and risks silent bugs.
- Pointer receivers on tiny types — copying an int via value is faster than dereferencing a pointer.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…