Comportement étrange d'"ajout" de Golang : écrasement des valeurs dans une tranche
En Golang, lors de l'ajout à une tranche, il est essentiel de comprendre la distinction entre les types pointeur et non-pointeur.
Considérons l'exemple code :
import "fmt" type Foo struct { val int } func main() { var a = make([]*Foo, 1) a[0] = &Foo{0} var b = [3]Foo{Foo{1}, Foo{2}, Foo{3}} for _, e := range b { a = append(a, &e) } for _, e := range a { fmt.Printf("%v ", *e) } }
Le résultat attendu est {0} {1} {2} {3}, mais à la place, il imprime {0} {3} {3} {3}. En effet, la boucle for opère sur des copies des éléments du tableau.
Lors d'une itération avec la plage for ..., une variable de boucle temporaire est créée et affectée à la valeur de l'élément du tableau. Dans ce cas, la variable temporaire est de type Foo. Cependant, lors de l'ajout à la tranche, l'adresse de la variable temporaire est ajoutée à la place de l'adresse de l'élément réel du tableau.
Cette variable temporaire est écrasée à chaque itération de boucle par la valeur du dernier élément de la tranche. tableau, qui est Foo{3}. Par conséquent, la tranche contient plusieurs références au même pointeur, pointant vers le dernier élément du tableau.
Pour résoudre le problème, l'adresse de l'élément du tableau au lieu de la variable de boucle doit être ajoutée :
for i := range b { a = append(a, &b[i]) }
Avec cette modification, le résultat est comme prévu : {0} {1} {2} {3}.
Ce comportement met en évidence l'importance de comprendre Le système de types de Go et la distinction entre les pointeurs et les non-pointeurs lorsque vous travaillez avec des tranches.
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!