Maison  >  Article  >  développement back-end  >  Pourquoi le report de la capture de fermeture dans Go entraîne-t-il un comportement inattendu ?

Pourquoi le report de la capture de fermeture dans Go entraîne-t-il un comportement inattendu ?

Linda Hamilton
Linda Hamiltonoriginal
2024-11-10 19:35:02476parcourir

Why Does Deferring Closure Capture in Go Lead to Unexpected Behavior?

Capture de fermeture différée dans Go

L'instruction defer de Go peut être utilisée pour exécuter une fonction après le retour de la fonction environnante. Cependant, lorsqu'il est utilisé avec des fermetures, il est important de comprendre comment fonctionne la capture des paramètres.

Le problème

Considérez le code suivant :

package main

import "fmt"

func main() {
    var whatever [5]struct{}

    for i := range whatever {
        fmt.Println(i)
    } // part 1

    for i := range whatever {
        defer func() { fmt.Println(i) }()
    } // part 2

    for i := range whatever {
        defer func(n int) { fmt.Println(n) }(i)
    } // part 3
}

La sortie du code est :

0
1
2
3
4
4
3
2
1
0
4
4
4
4
4

Analyse

  • Partie 1 : Imprime le compteur de boucle i comme prévu.
  • Partie 2 : Capture la variable i dans la fermeture. Cependant, lorsque la fermeture s'exécute, i a la valeur de la dernière itération de la boucle, qui est 4. Par conséquent, il affiche "44444".
  • Partie 3 : Ne capture pas toutes les variables externes. La fermeture est évaluée lors de l'exécution de l'instruction defer, de sorte que chaque appel defer a une valeur différente de n, ce qui donne "43210".

Différences clés

La différence cruciale entre les parties 2 et 3 réside dans le fait que la fermeture capture ou non les variables externes. Dans la partie 2, la fermeture capture i, qui est une référence à une variable externe. Dans la partie 3, la fermeture n'a pas de références externes, donc chaque appel a une valeur différente de n.

Considérations supplémentaires

  • Les appels différés sont exécuté dans l'ordre du dernier entré, premier sorti (LIFO) avant le retour de la fonction environnante.
  • L'expression évaluée lors de l'exécution de l'instruction defer, pas la fonction elle-même.

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