I don't understand what is going on in this code.
The receiver func works on the original structure user (because of the pointer), so inside func we change the original obj. But is the structure address also the original or a copy of the original "a"?
func main() { a := address{"freedom", "kyiv"} u := user{"valeriy", "zalyzhnyi", a} fmt.println(a) fmt.println(u) u.updatestreet("peremohy") fmt.println(a) fmt.println(u) } func (u *user) updatestreet(street string) { u.address.street = street } type user struct { firstname string lastname string address address } type address struct { street string city string }
This is my output
{Freedom Kyiv} {Valeriy Zalyzhnyi {Freedom Kyiv}} {Freedom Kyiv} {Valeriy Zalyzhnyi {Peremohy Kyiv}}
From this I understand that u.address has changed, and I also see that the "a" inside the "u" is different from the original obj. So what exactly happens behind the scenes and in memory? Based on the output, this behavior is completely unexpected to me. I expected that due to the presence of pointers we use the original objects ("a" and "u") in both cases. The second time (after func 'update..') printing fmt.println(a) will give us {peremohy kyiv}, because the second time fmt.println(u) gives us {valeriy zalyzhnyi {peremohy kyiv}}
To understand what is going on behind the scenes, it may be useful to visualize what the code does:
a = address{} u := user{address: a}
is subdivided into:
| variable value | memory address | | a = address{} | 0x000001 | | u = user{} | 0x000002 | | u.address = copy of a | 0x000003 |
So you have allocated memory for 1 user{}
instance and 2 address{}
instances. The value of the second address instance is an exact copy of the first address instance (at the time the copy was created).
Now when you call updatestreet
it is called on u
via a pointer, it does not create a copy of the user
instance but instead operates on memory address 0x000002
, so it actually operates on the same a
variable. Therefore the expression:
u.address.street = "foo"
Translates to: On the value held at memory address 0x000002, access the field named address
, within which field street
is accessed and assigned a new value. Let's map this onto the table we created above:
0x000002 -> address (which is stored in 0x000003) | --> set street to "foo"
After the function returns, we still have the same object at the same location in memory as before, but because we accessed the value of a
through the address in memory, the updatestreet
function The change has been made to the value of u
(since we used the same memory address).
Variable a
is copied
when assigned to u.address, so its memory address is unknown, or passed to the updatestreet
function , therefore remains unchanged.
The above is the detailed content of What goes on behind the scenes of these structures? Will the struct be copied?. For more information, please follow other related articles on the PHP Chinese website!