Pointer receiver (*T) — method operates on the original value via pointer, can modify it, avoids copying large structs. Value receiver (T) — method operates on a copy, changes are discarded after the method returns.
The choice is fundamental to Go method design. Pointer receivers are the only way to mutate a receiver's fields from within a method. They also avoid the overhead of copying large structs.
1type Buffer struct {2 data []byte3}45// Pointer receiver — modifies original6func (b *Buffer) Write(p []byte) (int, error) {7 b.data = append(b.data, p...)8 return len(p), nil9}1011// Value receiver — read-only, safe12func (b Buffer) Len() int {13 return len(b.data)14}
Value receivers are appropriate for small, immutable types where copying is trivial and you want read-only semantics. They provide encapsulation by working on a snapshot.
1type Point struct{ X, Y float64 }23func (p Point) DistanceTo(q Point) float64 {4 dx := p.X - q.X5 dy := p.Y - q.Y6 return math.Sqrt(dx*dx + dy*dy)7}
When to use:
Common mistakes: