Using a setter for a struct type does not work as anticipated
That's the difference between call by value and call by reference. If you are from C++ background , then you would know that it's the same in C++ also. And if you are from java background, then remember all object references are just pointers to the objects really..(meaning to say, when we do Node node = new Node();.. the node is holding the address of the new node object created). Therefore any method on the object(node) is actually called by reference(because node itself is a pointer).. so it reduces back to the same example as above.
Here is the fundamental understanding you are missing: when a struct is passed in to a function as a pointer, the function can modify the original struct because it has a pointer to it. However, when a struct is passed in to a function via its value, then a NEW copy of the struct is actually created just for that function call, and any modifications to this new copy of the struct will not affect the original struct.
You can prove that this is the way it works by printing out the actual addresses of the structs in question:
package main
import "fmt"
type T struct { Val string }
func (t T) SetVal( s string ) {
fmt.Printf("Address of copy is %p\n", &t);
}
func (t *T) SetVal2( s string ) {
fmt.Printf("Pointer argument is %p\n", t);
}
func main() {
v := T{"abc"}
fmt.Printf("Address of v is %p\n", &v);
v.SetVal("pdq")
v.SetVal2("xyz")
}
The code above results in this output when I run it in the Go playground:
Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290
Notice how the first and third pointer printed out are equal, which means they are the same struct. But the second pointer is different because it is a copy.
This seems to be exactly the same way that C structs / function parameters work, by the way.