What goes on behind the scenes of these structures? Will the struct be copied?

PHPz
Release: 2024-02-05 23:27:03
forward
818 people have browsed it

这些结构的幕后发生了什么? struct 会被复制吗?

Question content

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
}
Copy after login

This is my output

{Freedom Kyiv}
{Valeriy Zalyzhnyi {Freedom Kyiv}}
{Freedom Kyiv}
{Valeriy Zalyzhnyi {Peremohy Kyiv}}
Copy after login

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}}


Correct answer


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}
Copy after login

is subdivided into:

| variable value        | memory address |
| a = address{}         | 0x000001       |
| u = user{}            | 0x000002       |
| u.address = copy of a | 0x000003       |
Copy after login

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"
Copy after login

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"
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!