Comprendre comment fonctionne le différé de Go

Je pensais à différer pour le traitement que je voulais exécuter à la fin de la fonction, mais j'ai essayé de creuser plus profondément dans différer pour le comprendre correctement.

Une explication approximative du report

--Si vous décrivez le processus avec defer, il sera exécuté à la fin de func. --Dans l'exemple ci-dessous, "Today" est exécuté et la fin de func est atteinte, donc "It's Friday" est exécuté après cela.

func hogehoge() {
    defer fmt.Println("C'est vendredi.")
    fmt.Println("aujourd'hui....")
}
aujourd'hui....
C'est vendredi.

Un peu de creusage profond

Selon l'explication de Tour of Go

  1. L'exécution est reportée jusqu'à ce que la fonction incluse soit renvoyée.
  2. Les arguments de l'appel différé sont évalués immédiatement, mais sont reportés jusqu'à ce que l'exécution soit renvoyée.

Il y a une explication. Je peux comprendre 1 d'une manière ou d'une autre, mais j'étais curieux de connaître la description de 2 ** «immédiatement évalué» **, alors j'aimerais l'expliquer en détail plus tard.

Aussi, selon l'explication de Programming Language Go

  1. En utilisant le report, vous pouvez clairement décrire la libération des ressources.
  2. La position correcte du report est immédiatement après l'acquisition réussie des ressources

Il y a une explication à cet effet. Ce qui suit est un exemple.

resp, err := http.Get(url)
defer resp.Body.Close() //En fait, le jugement d'erreur doit être mis avant le report

En Java, close () est souvent écrit à la fin d'une fonction, et parfois j'oublie d'écrire close (), mais Si c'est le cas, il est recommandé de mettre le processus de libération immédiatement après l'acquisition de la ressource en utilisant defer.

Que signifie être évalué immédiatement?

Je pense qu'il est plus rapide de regarder le code, alors jetez un œil à l'exemple ci-dessous.

func main() {
    defer today()()
    fmt.Println("aujourd'hui....")
}

func today() func() {
    fmt.Println("Est-ce vendredi?")
    return func() {fmt.Println("Ou est-ce samedi?")}
}

Et si tu fais ça? Puisque le report est appelé à la fin de main, aujourd'hui ... '' est appelé en premier, puis Vendredi en aujourd'hui ()? , Enfin` ou samedi? Vous pourriez vous demander si ça va être ''.

Mais quand je l'essaye

Est-ce vendredi?
aujourd'hui....
Ou est-ce samedi?

Il devient. Pourquoi? Le fait est que la valeur de retour de today () est fonctionnelle.

L'argument de l'appel ** différé dans la section précédente est évalué immédiatement, mais veuillez faire attention à la partie **.

defer today()()L'évaluation est effectuée dans la partie description de.(Pourquoi y a-t-il deux parenthèses? Vous pouvez réfléchir un instant, mais j'aimerais expliquer à la fin parce que l'histoire est éteinte.)

Donc

fmt.Println("Est-ce vendredi?")

Est exécuté. Après cela, passez au traitement en main

fmt.Println("aujourd'hui....")

Est exécuté.

Puis avec une exécution retardée

fmt.Println("Ou est-ce samedi?")

C'est un flux.

Pourquoi y a-t-il deux parenthèses pour reporter aujourd'hui () ()? ??

N'a-t-il pas 2 crochets? ?? Vous pourriez penser, mais c'est nécessaire. Que se passe-t-il si vous essayez d'utiliser une parenthèse?

func main() {
    defer today()
    fmt.Println("aujourd'hui....")
}

func today() func() {
    fmt.Println("Est-ce vendredi?")
    return func() {fmt.Println("Ou est-ce samedi?")}
}
 aujourd'hui....
 Est-ce vendredi?

L'ordre a changé et samedi a disparu. .. .. ..

defer today() //1
defer today()() //2

Les deux descriptions sont fondamentalement différentes.

1 est le processus de report pour exécuter la fonction d'aujourd'hui. Autrement dit, aujourd'hui à la fin de la fonction principale()Est exécuté. Dans ce processus, la fonction anonyme est renvoyée, mais la fonction anonyme n'est pas exécutée.

D'autre part, 2 est aujourd'hui()La fonction renvoyée dans est exécutée à la fin de la fonction principale. Pour le décrire d'une manière facile à comprendre, 2 est une fonction anonyme dans le traitement du report.func() {fmt.Println("Ou est-ce samedi?")}Est en cours d'exécution.

Recommended Posts

Comprendre comment fonctionne le différé de Go
Comprendre le fonctionnement de l'API Zabbix
Fonctionnement de l'importation de modules Python
Compréhension du mécanisme Twilio # 1 - Introduction