Methods and pointer indirection

Comparing the previous two programs, you might notice that functions with a pointer argument must take a pointer:

  1. var v Vertex
  2. ScaleFunc(v, 5) // Compile error!
  3. ScaleFunc(&v, 5) // OK

while methods with pointer receivers take either a value or a pointer as the receiver when they are called:

  1. var v Vertex
  2. v.Scale(5) // OK
  3. p := &v
  4. p.Scale(10) // OK

For the statement v.Scale(5), even though v is a value and not a pointer, the method with the pointer receiver is called automatically. That is, as a convenience, Go interprets the statement v.Scale(5) as (&v).Scale(5) since the Scale method has a pointer receiver.

indirection.go

  1. package main
  2. import "fmt"
  3. type Vertex struct {
  4. X, Y float64
  5. }
  6. func (v *Vertex) Scale(f float64) {
  7. v.X = v.X * f
  8. v.Y = v.Y * f
  9. }
  10. func ScaleFunc(v *Vertex, f float64) {
  11. v.X = v.X * f
  12. v.Y = v.Y * f
  13. }
  14. func main() {
  15. v := Vertex{3, 4}
  16. v.Scale(2)
  17. ScaleFunc(&v, 10)
  18. p := &Vertex{4, 3}
  19. p.Scale(3)
  20. ScaleFunc(p, 8)
  21. fmt.Println(v, p)
  22. }