Pointer receiver methods can update the value they are called on.

pointer receiver A method with a pointer receiver can modify fields on the original value.

Pointer Receivers

step
pointer_receiver.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

type Counter struct {
	Value int
}

func (c *Counter) Add(delta int) {
	c.Value += delta
}

func main() {
	var step = 3
	counter := Counter{Value: 2}
	counter.Add(step)

	fmt.Println("step=", step)
	fmt.Println("value=", counter.Value)
}
package main

import "fmt"

type Counter struct {
	Value int
}

func (c *Counter) Add(delta int) {
	c.Value += delta
}

func main() {
	var step = 1
	counter := Counter{Value: 2}
	counter.Add(step)

	fmt.Println("step=", step)
	fmt.Println("value=", counter.Value)
}
package main

import "fmt"

type Counter struct {
	Value int
}

func (c *Counter) Add(delta int) {
	c.Value += delta
}

func main() {
	var step = 5
	counter := Counter{Value: 2}
	counter.Add(step)

	fmt.Println("step=", step)
	fmt.Println("value=", counter.Value)
}
  1. step ← 3, counter ← main.Counter{Value:2}

    13func main() {14  var step→ 3 = 3 //@step=1, 515  counter→ main.Counter{Value:2} := Counter{Value: 2}16  countermain.Counter{Value:2}.Add(step3)
  2. c.Value ← 5

    9func (c *Counter) Add(delta3 int) {10  c.Value→ 5 += delta311}
  3. counter ← main.Counter{Value:5}

    15  counter := Counter{Value: 2}16  counter→ main.Counter{Value:5}.Add(step3)1718  fmt.Println("step=", step3)19  fmt.Println("value=", counter.Value5)20}
    outputstep= 3
    value= 5
  1. step ← 1, counter ← main.Counter{Value:2}

    13func main() {14  var step→ 1 = 115  counter→ main.Counter{Value:2} := Counter{Value: 2}16  countermain.Counter{Value:2}.Add(step1)
  2. c.Value ← 3

    9func (c *Counter) Add(delta1 int) {10  c.Value→ 3 += delta111}
  3. counter ← main.Counter{Value:3}

    15  counter := Counter{Value: 2}16  counter→ main.Counter{Value:3}.Add(step1)1718  fmt.Println("step=", step1)19  fmt.Println("value=", counter.Value3)20}
    outputstep= 1
    value= 3
  1. step ← 5, counter ← main.Counter{Value:2}

    13func main() {14  var step→ 5 = 515  counter→ main.Counter{Value:2} := Counter{Value: 2}16  countermain.Counter{Value:2}.Add(step5)
  2. c.Value ← 7

    9func (c *Counter) Add(delta5 int) {10  c.Value→ 7 += delta511}
  3. counter ← main.Counter{Value:7}

    15  counter := Counter{Value: 2}16  counter→ main.Counter{Value:7}.Add(step5)1718  fmt.Println("step=", step5)19  fmt.Println("value=", counter.Value7)20}
    outputstep= 5
    value= 7

Follow the Pointer Receiver

  1. step starts as 3.
  2. counter starts with Value: 2.
  3. counter.Add(step) calls a method with a pointer receiver.
  4. The method adds 3 to the original counter value.
  5. The program prints step= 3 and value= 5. | starting value | step | final value | | --- | --- | --- | | 2 | 3 | 5 | | 2 | 1 | 3 | | 2 | 5 | 7 |

Exercise: pointer_receiver.go

Reproduce step= 3 and value= 5, then use the pinned step variants 1 and 5 to predict value= 3 and value= 7.