Maison >développement back-end >Golang >Pourquoi la boucle « range » de Go produit-elle des résultats différents avec des structures de boucle variables ?

Pourquoi la boucle « range » de Go produit-elle des résultats différents avec des structures de boucle variables ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-19 18:20:10988parcourir

Why Does Go's `range` Loop Produce Different Results with Varying Loop Structures?

Comprendre les différentes variations de boucle dans Go

Lors de l'itération sur une tranche dans Go, vous pouvez rencontrer un comportement inattendu lors de l'utilisation de la méthode range. Voyons pourquoi différentes variations de boucle peuvent produire des résultats différents.

Le problème

Considérez les deux variations de boucle for suivantes :

loop1() {
    for _, cmd := range cmds {
        // Store a function literal that references the loop variable cmd
        actions[cmd] = func() {
            fmt.Println(cmd)
        }
    }
}
loop2() {
    for i, cmd := range cmds {
        // Capture the loop variable cmd using a new variable
        command := cmds[i]
        actions[cmd] = func() {
            fmt.Println(command)
        }
    }
}

Exécuter les résultats de ces boucles dans différentes sorties :

  • loop1() : Imprime "mettre à jour" trois fois
  • loop2() : Imprime "supprimer", "mettre à jour" et "créer"

L'explication

Le problème avec loop1() survient car les littéraux de fonction stockés dans la carte d'actions font référence à la variable de boucle cmd. Puisqu'il n'y a qu'une seule instance de cette variable de boucle, toutes les fonctions stockées dans la carte y feront référence.

Une fois la boucle terminée, la valeur de cmd sera le dernier élément de la tranche cmds, "update. " Par conséquent, lorsque les fonctions de la carte d'actions sont exécutées, elles imprimeront toutes "update".

Pour contourner ce problème, loop2() capture la variable de boucle cmd à l'aide d'une nouvelle variable, command. Cela crée une copie "détachée" de la variable de boucle pour chaque itération, qui n'est pas affectée par la variable de boucle une fois la boucle terminée.

En conséquence, chaque fonction stockée dans la carte d'actions dans loop2() a sa propre copie de la variable de boucle, qui permet à chaque fonction d'imprimer la commande correcte.

Conclusion

Lors de l'analyse d'une tranche, il est important de savoir que la variable de boucle est partagé entre toutes les itérations. Pour éviter un comportement inattendu, il est recommandé de capturer ou de détacher la variable de boucle à l'aide d'une nouvelle variable, en particulier lorsque vous utilisez des littéraux de fonction qui seront exécutés après la boucle.

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:
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