php La gamme environnementale contenue dans le milieu fermé fait référence aux éléments, facteurs et conditions contenus dans le milieu fermé. Un environnement fermé fait référence à un espace ou une plage relativement fermé et restreint, qui peut être un espace physique, tel qu'un laboratoire ou une usine, ou un espace virtuel, tel qu'un réseau informatique. Dans un environnement fermé, divers facteurs tels que la température, l'humidité, la composition des gaz, etc. peuvent être contrôlés et ajustés pour atteindre des objectifs spécifiques. Les environnements fermés sont courants dans les expériences de recherche scientifique, la production et la fabrication et dans d'autres domaines, et jouent un rôle important pour garantir la précision expérimentale et la qualité des produits.
J'ai imité des tutoriels en ligne sur les fermetures et j'ai écrit le code suivant.
func foo1() func() { xvalue := 1 x := &xvalue defer func() { xvalue = 2 }() return func() { *x = *x + 1 fmt.printf("foo1 val = %d\n", *x) } } func main() { f1 := foo1() f1() f1() f1() }
Je suis confus, lors de l'exécution f1 := foo1()
后,变量 xvalue
似乎应该被回收,因此使用 *x
cela devrait être faux, mais le code ci-dessus ne contient aucune erreur et s'exécute correctement, donnant le résultat
foo1 val = 3 foo1 val = 4 foo1 val = 5
Je veux donc savoir si la fermeture enregistre la valeur du pointeur en plus du pointeur lui-même, ou est-ce que le mécanisme de garbage collection du langage go empêche la suppression de la valeur x ?
Dans Go, une fermeture obtient une référence à (l'adresse de) toute variable qu'elle ferme. Citation Référence linguistique :
Les littéraux de fonction sont des fermetures : ils peuvent référencer des variables définies dans les fonctions environnantes. Ces variables sont ensuite partagées entre les fonctions environnantes et les littéraux de fonction, et elles persistent tant qu'elles sont accessibles.
Donc, dans votre exemple :
f1 := foo1()
xValue
(le compilateur peut l'allouer sur le tas). Il commencera avec une valeur nulle de 0 pour son type. x
存在并为其分配 xValue
et attribuez-lui l'adresse de defer
-red 闭包运行并将值 2 分配给 xValue
defer
-rouge s'exécute et attribue la valeur 2 à x
Renvoie une variable de fermeture de fermeture
x
,编译器保证即使在 foo
返回后该变量也存在。由于 x
包含 xValue
Ce dernier point peut être un peu délicat : puisque la fermeture renvoyée fait référence à la variable xValue
, le compilateur garantit que la variable existe même après le retour de foo
. Puisque
xValue
🎜 🎜Pour résumer, peut-être que vous trébuchez sur les connaissances C++, une fois le contrôle renvoyé par la fonction, toute variable déclarée dans la fonction n'existe plus, donc toute référence à cette variable qui existe en dehors de la fonction devient invalide. Dans Go, ce n'est pas le cas : le langage est explicitement défini pour être sûr à cet égard : le compilateur garantit que toute variable a une allocation appropriée de sorte que lorsqu'une référence à celle-ci est renvoyée (ou autrement transmise) lors de sa création, la fonction appels. A partir de cette fonction, des appels sont effectués vers le monde extérieur. 🎜
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!