Maison  >  Article  >  développement back-end  >  Que se passe-t-il dans les coulisses de ces structures ? La structure sera-t-elle copiée ?

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

PHPz
PHPzavant
2024-02-05 23:27:03821parcourir

这些结构的幕后发生了什么? 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
}

Voici ma sortie

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

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}

est subdivisé en :

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

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"

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"
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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer