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
methodand afunctionis that amethodbelongs to atype, whereas afunctionbelongs to apackage. - Consistent Design Tip: When one of the
methodsin anytypeare usingpointer receiver, it is better to convert allmethod receiversof thattypetopointer receivers. - We (must) use a
pointer receiverwhen we want to make changes to areceiver variable. In other words, use apointer receiverwhen the received value intomethodis going to be very large.