Maison >développement back-end >Golang >Que se passe-t-il dans les coulisses de ces structures ? La structure sera-t-elle copiée ?
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}}
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!