Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Apa yang berlaku di sebalik tabir struktur ini? Adakah struct akan disalin?

Apa yang berlaku di sebalik tabir struktur ini? Adakah struct akan disalin?

PHPz
PHPzke hadapan
2024-02-05 23:27:03876semak imbas

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

Kandungan soalan

Saya tidak faham apa yang berlaku dalam kod ini.

Fungsi penerima berfungsi pada pengguna struktur asal (kerana penunjuk), jadi di dalam func kami menukar obj asal. Tetapi adakah alamat struktur juga asal atau salinan asal "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
}

Ini hasil keluaran saya

{Freedom Kyiv}
{Valeriy Zalyzhnyi {Freedom Kyiv}}
{Freedom Kyiv}
{Valeriy Zalyzhnyi {Peremohy Kyiv}}

Daripada ini saya faham bahawa alamat u telah berubah, dan saya juga melihat bahawa "a" di dalam "u" adalah berbeza daripada obj asal. Jadi apa sebenarnya yang berlaku di sebalik tabir dan dalam ingatan? Berdasarkan output, tingkah laku ini benar-benar tidak dijangka kepada saya. Saya menjangkakan bahawa disebabkan kehadiran penunjuk kami menggunakan objek asal ("a" dan "u") dalam kedua-dua kes. Kali kedua (selepas func 'kemas kini..') mencetak fmt.println(a) akan memberi kami {peremohy kyiv}, kerana kali kedua fmt.println(u) memberi kami {valeriy zalyzhnyi {peremohy kyiv}}


Jawapan Betul


Untuk memahami perkara yang berlaku di sebalik tabir , adalah berguna untuk menggambarkan perkara yang dilakukan oleh kod:

a = address{}
u := user{address: a}

terbahagi kepada:

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

Jadi anda telah memperuntukkan memori untuk 1 user{} 实例和 2 个 address{} contoh. Nilai contoh alamat kedua ialah salinan tepat contoh alamat pertama (pada masa salinan dibuat).

Sekarang, apabila anda memanggil updatestreet 时,它是通过指针在 u 上调用的,它不会创建 user 实例的副本,而是对内存地址 0x000002 进行操作,因此它实际上对同一个 a pembolehubah beroperasi. Oleh itu ungkapan:

u.address.street = "foo"

diterjemahkan kepada: Pada nilai yang dipegang pada alamat memori 0x000002, akses nilai bernama address 的字段,在该字段中,访问字段 street dan tetapkan nilai baharu. Mari petakan ini pada jadual yang kami buat di atas:

0x000002 -> address (which is stored in 0x000003)
              |
              --> set street to "foo"
Selepas fungsi

kembali, kita masih mempunyai objek yang sama di lokasi yang sama dalam ingatan seperti sebelumnya, tetapi kerana kita mengakses nilai a 的值,所以 updatestreet 函数所做的更改已经完成为 u melalui alamat dalam ingatan (kerana kita menggunakan alamat memori yang sama).

Fungsi a 在赋值给 u.address 时被复制,因此它的内存地址未知,或者传递给 updatestreet Boleh ubah dan oleh itu kekal tidak berubah.

Atas ialah kandungan terperinci Apa yang berlaku di sebalik tabir struktur ini? Adakah struct akan disalin?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam