Maison > développement back-end > Golang > le corps du texte

Que se passe-t-il dans les coulisses de ces structures ? La structure sera-t-elle copiée ?

PHPz
Libérer: 2024-02-05 23:27:03
avant
876 Les gens l'ont consulté

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

Contenu de la question

Je ne comprends pas ce qui se passe dans ce code.

La fonction récepteur fonctionne sur l'utilisateur de la structure d'origine (à cause du pointeur), donc à l'intérieur de la fonction, nous modifions l'objet d'origine. Mais l'adresse de la structure est-elle également l'original ou une copie du « a » original ?

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
}
Copier après la connexion

Voici ma sortie

{Freedom Kyiv}
{Valeriy Zalyzhnyi {Freedom Kyiv}}
{Freedom Kyiv}
{Valeriy Zalyzhnyi {Peremohy Kyiv}}
Copier après la connexion

De là, je comprends que u.address a changé, et je vois aussi que le "a" à l'intérieur du "u" est différent de l'objet d'origine. Alors, que se passe-t-il exactement dans les coulisses et dans la mémoire ? D'après le résultat, ce comportement m'est complètement inattendu. Je m'attendais à ce qu'en raison de la présence de pointeurs, nous utilisions les objets d'origine ("a" et "u") dans les deux cas. La deuxième fois (après func 'update..') l'impression de fmt.println(a) nous donnera {peremohy kyiv}, car la deuxième fois fmt.println(u) nous donne {valeriy zalyzhnyi {peremohy kyiv}}


Bonne réponse


Pour comprendre ce qui se passe dans les coulisses , il peut être utile de visualiser ce que fait le code :

a = address{}
u := user{address: a}
Copier après la connexion

est subdivisé en :

| variable value        | memory address |
| a = address{}         | 0x000001       |
| u = user{}            | 0x000002       |
| u.address = copy of a | 0x000003       |
Copier après la connexion

Vous avez donc alloué de la mémoire pour 1 user{} 实例和 2 个 address{} instance. La valeur de la deuxième instance d'adresse est une copie exacte de la première instance d'adresse (au moment de la création de la copie).

Maintenant, lorsque vous appelez updatestreet 时,它是通过指针在 u 上调用的,它不会创建 user 实例的副本,而是对内存地址 0x000002 进行操作,因此它实际上对同一个 a, la variable fonctionne. D'où l'expression :

u.address.street = "foo"
Copier après la connexion

se traduit par : Sur la valeur détenue à l'adresse mémoire 0x000002, accédez à la valeur nommée address 的字段,在该字段中,访问字段 street et attribuez-lui une nouvelle valeur. Mappons cela sur le tableau que nous avons créé ci-dessus :

0x000002 -> address (which is stored in 0x000003)
              |
              --> set street to "foo"
Copier après la connexion
Après le retour de la fonction

, nous avons toujours le même objet au même endroit en mémoire qu'avant, mais parce que nous avons accédé à la valeur de a 的值,所以 updatestreet 函数所做的更改已经完成为 u via une adresse en mémoire (puisque nous avons utilisé la même adresse mémoire).

Variable a 在赋值给 u.address 时被复制,因此它的内存地址未知,或者传递给 updatestreet et reste donc inchangé.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!