Choosing a value or pointer receiver

There are two reasons to use a pointer receiver.

The first is so that the method can modify the value that its receiver points to.

The second is to avoid copying the value on each method call. This can be more efficient if the receiver is a large struct, for example.

In this example, both Scale and Abs are with receiver type *Vertex, even though the Abs method needn't modify its receiver.

In general, all methods on a given type should have either value or pointer receivers, but not a mixture of both. (We'll see why over the next few pages.)

methods-with-pointer-receivers.go

  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. type Vertex struct {
  7. X, Y float64
  8. }
  9. func (v *Vertex) Scale(f float64) {
  10. v.X = v.X * f
  11. v.Y = v.Y * f
  12. }
  13. func (v *Vertex) Abs() float64 {
  14. return math.Sqrt(v.X*v.X + v.Y*v.Y)
  15. }
  16. func main() {
  17. v := &Vertex{3, 4}
  18. fmt.Printf("Before scaling: %+v, Abs: %v\n", v, v.Abs())
  19. v.Scale(5)
  20. fmt.Printf("After scaling: %+v, Abs: %v\n", v, v.Abs())
  21. }