Method receiver vs Pointer receiver

Struct values when used as method receivers are exactly that values and so are a shallow copy of the value allocated a new portion of memory. The effects are not observed outside of the method as there are no references to the new value and so it is garbaged collected.

Pointer receivers allow mutation of what the pointer points to. Your function is recieving a pointer to the same address in memory even in the function stackframe.

package main

import "fmt"

type test_struct struct {
    Message string
}

//value reciever
func (t test_struct) Say() {
    fmt.Println(t.Message)
}

//value reciever
func (t test_struct) Update(m string) {
    t.Message = m
}

//pointer reciever
func (t *test_struct) SayP() {
    fmt.Println(t.Message)
}

//pointer reciever
func (t *test_struct) UpdateP(m string) {
    t.Message = m
}

func main() {
    ts := test_struct{}
    //call update on the value reciever
    ts.Update("test")
    ts.Say()
    //call update on the value reciever
    ts.Update("test2")
    ts.Say()
    //assign to the ts value created in this function
    ts.Message = "test2"
    ts.Say()
    //create a pointer
    tsp := &test_struct{}
    //set a value on the pointer
    tsp.Message = "test"
    tsp.SayP()
    //update the pointer
    tsp.UpdateP("test2")
    tsp.SayP()
}

//outputs
//
//
//test2
//test
//test2

Recall that essentially what is happening here is

Update(ts,"test")

So we are being passed a value and the value is being copied to the funtions stackframe. This is the same as if we were to do the following in Javascript :

var str = "mystring";

function add(mystr){
    mystr += "hasnt changed";
}

add(str);

console.log(str); //outputs mystring

Note:

  • The only difference between method and a function is that a method belongs to a type, whereas a function belongs to a package.
  • Consistent Design Tip: When one of the methods in any type are using pointer receiver, it is better to convert all method receivers of that type to pointer receivers.
  • We (must) use a pointer receiver when we want to make changes to a receiver variable. In other words, use a pointer receiver when the received value into method is going to be very large.

See also