Maison > développement back-end > Golang > le corps du texte

Pourquoi `defer func() { fmt.Println(i) }()` imprime '44444' dans Go, alors que `defer func(n int) { fmt.Println(n) }(i)` imprime correctement '43210' ?

DDD
Libérer: 2024-11-10 18:54:02
original
425 Les gens l'ont consulté

Why does `defer func() { fmt.Println(i) }()` print

Appels de fonction différés et capture de fermeture

Dans Go, l'instruction defer nous permet d'exécuter une fonction juste avant le retour de la fonction environnante. Un aspect important de Defer est la façon dont il gère les fermetures.

Dans cet extrait de code :

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

La partie 1 imprime simplement les valeurs de i de 0 à 4. La partie 2, cependant, démontre un comportement intéressant. Au lieu d'imprimer les valeurs attendues de 0 à 4, il affiche "44444".

En effet, la fermeture de la partie 2 capture la variable i. Lorsque la fermeture est exécutée plus tard, la variable i a la valeur qu'elle avait lors de la dernière itération de l'instruction range, qui est 4. Par conséquent, toutes les fonctions différées appellent print 4.

En revanche, une partie 3 ne capture aucune variable externe. Selon les spécifications Go, "chaque fois que l'instruction 'defer' s'exécute, la valeur de la fonction et les paramètres de l'appel sont évalués comme d'habitude et enregistrés à nouveau, mais la fonction réelle n'est pas invoquée." Cela signifie que chacun des appels de fonction différés a une valeur différente du paramètre « n », qui est la valeur de « i » au moment où l'instruction « defer » a été exécutée.

Par conséquent, la partie 3 est correcte. affiche "43210" car les appels de fonction différés sont exécutés dans l'ordre LIFO (dernier entré, premier sorti) avant le retour de la fonction environnante.

Il est crucial de se rappeler que l'expression de fonction dans 'defer f()' n'est pas exécuté au moment de l'exécution de l'instruction defer, tandis que l'expression dans 'defer f(e)' est évaluée immédiatement.

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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal