Using a setter for a structure type does not work as expected

Using the setup function for the structure, but does not work as expected:

package main import "fmt" type T struct { Val string } // this setter seems not to work func (t T) SetVal( s string ) { t.Val = s } // this setter, using ptr to T, seems to work ok func (t *T) SetVal2( s string ) { (*t).Val = s } func main() { v := T{"abc"} fmt.Println( v ) // prints {abc} v.SetVal("pdq") fmt.Println( v ) // prints {abc}, was expecting {pdq}! v.SetVal2("xyz") fmt.Println( v ) // prints {xyz}! } 

I lack a fundamental understanding - why doesn't SetVal work?

the behavior is similar to setting values ​​in reflect which only works if the pointer points to the object and not to the object itself

+7
source share
2 answers

Here is a fundamental understanding that you lack: when a structure is passed to the function as a pointer, the function can change the original structure because it has a pointer to it. However, when the structure is passed to the function through its value, then in fact a NEW copy of the structure is created only for this function call, and any modifications to this new copy of the structure do not affect the original structure.

You can prove that this is how it works by printing out the actual addresses of the structures 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 above code leads to the conclusion when I run it on the Go playground:

 Address of v is 0xf840001290 Address of copy is 0xf8400013e0 Pointer argument is 0xf840001290 

Notice how the first and third pointers are printed, which means they have the same structure. But the second pointer is different because it is a copy.

By the way, this is similar to how the C structure / function parameters work.

+16
source

What is the difference between a call by value and a call by reference. If you are in the background of C ++, you would know that it is also in C ++. And if you are in the background of java, then remember that all references to objects are just pointers to objects in fact .. (which means when we do Node node = new Node (); .. Node holds the address of the newly created object Node). Therefore, any method of an object (node) is actually called by reference (because Node itself is a pointer) .. therefore it comes down to the same example as above.

+1
source

All Articles