Problème d'écrasement inattendu avec la fonction "append" de Go
Dans Go, la fonction d'ajout est fréquemment utilisée pour étendre des tranches avec des éléments supplémentaires. Cependant, un comportement inattendu peut parfois se produire lors de l'ajout de pointeurs vers des structures.
Considérez l'extrait de code suivant :
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) } }
Curieusement, au lieu d'imprimer {0} {1} {2} { 3}, le code génère {0} {3} {3} {3}. Ce comportement inattendu provient d'un aspect fondamental du comportement de Go :
Copies dans les boucles for Range
Go itère sur les tranches et les tableaux en utilisant les boucles for range, qui créent une copie de chaque élément au cours de l’itération. Dans notre code, la variable de boucle for range e représente une copie temporaire de l'élément de tableau b[i]. Malheureusement, nous ajoutons ensuite l'adresse de cette variable temporaire à la tranche a.
Le correctif
Pour résoudre ce problème, nous devons ajouter l'adresse de la élément de tableau original au lieu de la copie temporaire. En modifiant la boucle for pour utiliser l'index i, nous nous assurons que l'adresse correcte est ajoutée à la tranche :
for i := range b { a = append(a, &b[i]) }
Cette modification produit le résultat attendu de {0} {1} {2} {3 }.
Raison du comportement
Le manque de vraies références de Go contribue à ce comportement. En C ou Java, où des références sont utilisées, la variable de boucle ferait directement référence à l'élément du tableau, permettant des mutations via la variable de boucle. Cependant, dans Go, la variable de boucle est une variable distincte qui contient une copie de l'élément, pas une référence. Par conséquent, les modifications apportées à la variable de boucle ne sont pas reflétées dans les éléments du tableau d'origine.
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!