Dans Go, l'instruction "defer" nous permet de planifier l'exécution d'une fonction juste avant le retour de la fonction environnante. Cependant, cela peut prêter à confusion lorsqu'il s'agit de variables modifiées dans la fonction englobante.
Considérez la fonction suivante :
func printNumbers() { var x int defer fmt.Println(x) for i := 0; i < 5; i++ { x++ } }
Selon le Spécification Go, lorsqu'une instruction "defer" est exécutée, la valeur de la fonction et les paramètres sont évalués et stockés pour une exécution ultérieure. Cela signifie que lorsque la fonction sera finalement appelée, la valeur de x sera toujours 0 car elle a été évaluée au moment du report.
Pour résoudre ce problème, nous peut utiliser une fonction anonyme dans l'instruction "defer":
defer func() { fmt.Println(x) }()
Ici, x n'est pas un paramètre de la fonction anonyme, il ne sera donc pas évalué lorsque le L'instruction "defer" est exécutée. Au lieu de cela, la valeur de x sera capturée au moment où la fonction anonyme est appelée, garantissant que la valeur la plus à jour est imprimée.
Utilisation d'un pointeur :
var x int defer func() { fmt.Println(&x) }()
Cette approche utilise un pointeur vers x comme paramètre du différé fonction. Lorsque l'instruction "defer" est exécutée, seul le pointeur est évalué, pas la valeur de x. Lorsque la fonction différée est appelée, elle accédera à la valeur actuelle de x via le pointeur.
Utilisation d'un type personnalisé :
type MyInt int func (m *MyInt) String() string { return strconv.Itoa(int(*m)) } var x MyInt defer fmt.Println(&x)
Cette solution est similaire à l'approche pointeur mais utilise un type personnalisé (MyInt) qui implémente la méthode String(). En implémentant String(), nous pouvons contrôler la façon dont la valeur de x est imprimée.
Utiliser une tranche :
var x []int defer fmt.Println(x)
Le découpage est un type de descripteur en Go, ce qui signifie que sa valeur est une référence à un tableau sous-jacent. Lorsque nous différons une tranche, seule la référence est évaluée, pas les éléments réels du tableau. Par conséquent, toutes les modifications apportées aux éléments de tranche après le report seront reflétées dans la sortie imprimée.
Enveloppement dans une structure :
type Wrapper struct { Value int } var x Wrapper defer fmt.Println(&x)
Cette approche est similaire à l'utilisation d'un pointeur, mais nous enveloppons la valeur dans une structure pour éviter d'avoir à déréférencer le pointeur dans le différé fonction.
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!