Maison >développement back-end >Golang >Quelle est la gamme d'environnements contenus dans une fermeture ?

Quelle est la gamme d'environnements contenus dans une fermeture ?

WBOY
WBOYavant
2024-02-10 11:12:09994parcourir

Quelle est la gamme denvironnements contenus dans une fermeture ?

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.

Contenu de la question

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 ?

Solution de contournement

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 :

  1. f1 := foo1()

    1. Faire exister la variable xValue (le compilateur peut l'allouer sur le tas). Il commencera avec une valeur nulle de 0 pour son type.
    2. Faites exister la variable x 存在并为其分配 xValue et attribuez-lui l'adresse de
    3. .
    4. La fermeture defer-red 闭包运行并将值 2 分配给 xValuedefer-rouge s'exécute et attribue la valeur 2 à
    5. .
    6. xRenvoie une variable de fermeture de fermeture
    7. .

    x,编译器保证即使在 foo 返回后该变量也存在。由于 x 包含 xValueCe 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

    contient l'adresse de
  2. (et est donc une référence en direct à celle-ci), cette adresse existe toujours et ne peut pas être récupérée. En utilisant la même méthode d'analyse d'échappement, le compilateur garantit que
  3. survit au retour de sa fonction déclarée.

    xValue

  4. Vous exécutez la fermeture renvoyée, qui est modifiée par le pointeur vers celle-ci
– aucune magie ne se produit ici. Les deux autres appels effectuent la même opération.

🎜 🎜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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer