Heim >Backend-Entwicklung >Golang >Was passiert hinter den Kulissen dieser Strukturen? Wird die Struktur kopiert?

Was passiert hinter den Kulissen dieser Strukturen? Wird die Struktur kopiert?

PHPz
PHPznach vorne
2024-02-05 23:27:03902Durchsuche

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

Frageninhalt

Ich verstehe nicht, was in diesem Code vor sich geht.

Die Empfängerfunktion arbeitet mit dem ursprünglichen Strukturbenutzer (aufgrund des Zeigers), also ändern wir innerhalb der Funktion das ursprüngliche Objekt. Aber ist die Strukturadresse auch das Original oder eine Kopie des Originals „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
}

Das ist meine Ausgabe

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

Daraus geht hervor, dass sich u.address geändert hat, und ich sehe auch, dass sich das „a“ im „u“ vom ursprünglichen Objekt unterscheidet. Was genau passiert also hinter den Kulissen und in der Erinnerung? Basierend auf der Ausgabe ist dieses Verhalten für mich völlig unerwartet. Ich habe erwartet, dass wir aufgrund der Anwesenheit von Zeigern in beiden Fällen die Originalobjekte („a“ und „u“) verwenden. Beim zweiten Mal (nach func 'update..') erhalten wir durch Drucken von fmt.println(a) {peremohy kyiv}, denn beim zweiten Mal erhalten wir durch fmt.println(u) {valeriy zalyzhnyi {peremohy kyiv}}


Richtige Antwort


Um zu verstehen, was sich hinter den Kulissen abspielt , kann es hilfreich sein, sich vorzustellen, was der Code tut:

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

ist unterteilt in:

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

Sie haben also Speicher für 1 user{} 实例和 2 个 address{} Instanz zugewiesen. Der Wert der zweiten Adressinstanz ist eine exakte Kopie der ersten Adressinstanz (zum Zeitpunkt der Erstellung der Kopie).

Wenn Sie nun updatestreet 时,它是通过指针在 u 上调用的,它不会创建 user 实例的副本,而是对内存地址 0x000002 进行操作,因此它实际上对同一个 a aufrufen, wird die Variable aktiviert. Daher der Ausdruck:

u.address.street = "foo"

bedeutet übersetzt: Greifen Sie auf den an der Speicheradresse 0x000002 gehaltenen Wert auf den Wert mit dem Namen address 的字段,在该字段中,访问字段 street zu und weisen Sie ihm einen neuen Wert zu. Ordnen wir dies der Tabelle zu, die wir oben erstellt haben:

0x000002 -> address (which is stored in 0x000003)
              |
              --> set street to "foo"
Nachdem die Funktion

zurückkehrt, haben wir immer noch dasselbe Objekt an derselben Stelle im Speicher wie zuvor, aber weil wir über eine Adresse im Speicher auf den Wert von a 的值,所以 updatestreet 函数所做的更改已经完成为 u zugegriffen haben (da wir dieselbe Speicheradresse verwendet haben).

Variable a 在赋值给 u.address 时被复制,因此它的内存地址未知,或者传递给 updatestreet Funktion und bleibt daher unverändert.

Das obige ist der detaillierte Inhalt vonWas passiert hinter den Kulissen dieser Strukturen? Wird die Struktur kopiert?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen