Maison >développement back-end >Golang >Pourquoi la fonction « append » de Go produit-elle des résultats inattendus lors de l'ajout de pointeurs à partir d'une boucle de plage ?
Écrasement involontaire dans la fonction « ajouter » de Go
Dans Go, explorer les nuances de l'ajout à des tranches peut parfois conduire à des résultats inattendus. Examinons un exemple illustrant ce comportement.
Considérez le code suivant :
import "fmt" type Foo struct { val int } func main() { a := make([]*Foo, 1) a[0] = &Foo{0} 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}, la sortie se lit comme {0} {3} {3} {3}. Pour résoudre ce casse-tête, disséquons la fonction "append".
Dans Go, "append" attend un pointeur vers la tranche à laquelle nous ajoutons des éléments. Dans notre exemple, nous stockons correctement les pointeurs vers les instances « Foo » dans la tranche « a ».
Cependant, lors de la boucle sur les éléments du tableau « b », nous rencontrons un problème subtil. La syntaxe "range" parcourt une copie de chaque élément plutôt que l'élément lui-même. Par conséquent, nous ajoutons systématiquement des pointeurs vers des copies de l'instance "Foo" "e", qui pointe vers "Foo{3}" dans l'itération finale.
Pour corriger ce comportement, nous devons référencer les éléments réels de "b" dans notre opération "ajouter" :
for i := range b { a = append(a, &b[i]) }
Cette modification garantit que nous ajoutons des pointeurs directement aux éléments dans "b", ce qui donne le résultat souhaité : {0} {1} {2} {3}.
Comprendre la raison sous-jacente de ce comportement est crucial. Dans Go, les pointeurs sont des valeurs, interprétées comme des adresses mémoire lors de la manipulation des données. En tant que telles, les boucles « plage » parcourent des copies de valeurs plutôt que les objets d'origine. Cette connaissance aide à comprendre pourquoi dans notre code initial, trois éléments pointaient vers la même instance "Foo{3}".
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!