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 ?

Pourquoi la fonction « append » de Go produit-elle des résultats inattendus lors de l'ajout de pointeurs à partir d'une boucle de plage ?

Patricia Arquette
Libérer: 2024-12-08 03:08:11
original
245 Les gens l'ont consulté

Why Does Go's `append` Function Produce Unexpected Results When Appending Pointers from a Range Loop?

É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)
    }
}
Copier après la connexion

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])
}
Copier après la connexion

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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal