Maison > développement back-end > Golang > Pourquoi l'ajout de pointeurs dans une boucle Go `for...range` produit-il des résultats inattendus ?

Pourquoi l'ajout de pointeurs dans une boucle Go `for...range` produit-il des résultats inattendus ?

Barbara Streisand
Libérer: 2024-12-30 17:03:12
original
772 Les gens l'ont consulté

Why Does Appending Pointers in a Go `for...range` Loop Produce Unexpected Results?

Comprendre un comportement étrange avec ajout dans Go

Dans Go, la fonction d'ajout opère sur des tranches pour ajouter de nouveaux éléments. Cependant, les utilisateurs peuvent rencontrer un comportement inattendu lors de l'ajout de pointeurs vers des éléments d'un tableau dans une boucle for range.

Prenons l'exemple 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)
    }
}
Copier après la connexion

Résultat attendu : {0} {1} {2} {3}

Résultat réel : {0} {3} {3} {3}

Raison du comportement

Ce comportement inattendu se produit parce que la boucle for range parcourt une copie des éléments, et non les éléments d'origine eux-mêmes. Dans ce cas, la variable de boucle e contient une copie de l'élément actuel du tableau. Lorsque la tranche est ajoutée, l'adresse de la variable de boucle est ajoutée, qui fait référence au même emplacement mémoire pour toutes les itérations. Par conséquent, lorsque le dernier élément du tableau est rencontré, toutes les adresses ajoutées pointent vers le même élément.

Correction

Pour résoudre ce problème, la fonction d'ajout doit être utilisé avec l'adresse de l'élément de tableau d'origine, pas la variable de boucle. Voici le code corrigé :

for i := range b {
    a = append(a, &b[i])
}
Copier après la connexion

Avec cette modification, le résultat sera comme prévu : {0} {1} {2} {3}.

Conclusion

Comprendre la différence entre les pointeurs et les types non-pointeurs dans Go est crucial pour une bonne gestion des références mémoire. Lorsque vous utilisez des boucles for range, il est essentiel de déterminer si vous devez accéder à l'élément d'origine ou à une copie, et d'utiliser la syntaxe appropriée en conséquence.

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!

source:php.cn
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