Verstehe, wie Go's Defer funktioniert

Ich habe über eine Verzögerung für die Verarbeitung nachgedacht, die ich am Ende der Funktion ausführen wollte, aber ich habe versucht, mich eingehender mit der Verzögerung zu befassen, um sie richtig zu verstehen.

Eine grobe Erklärung des Aufschubs

func hogehoge() {
    defer fmt.Println("Es ist Freitag.")
    fmt.Println("heute....")
}
heute....
Es ist Freitag.

Ein bisschen tief graben

Nach der Erklärung von Tour of Go

  1. Die Ausführung wird verschoben, bis die beigefügte Funktion zurückgegeben wird.
  2. Die Argumente des Aufschubaufrufs werden sofort ausgewertet, aber verschoben, bis die Ausführung zurückgegeben wird.

Es gibt eine Erklärung. Ich kann 1 irgendwie verstehen, aber ich war neugierig auf die Beschreibung von 2 ** "sofort bewertet" **, deshalb möchte ich es später ausführlich erklären.

Gemäß der Erklärung von Programming Language Go

  1. Mit defer können Sie die Freigabe von Ressourcen klar beschreiben.
  2. Die korrekte Position des Aufschubs ist unmittelbar nach erfolgreicher Beschaffung von Ressourcen

Dafür gibt es eine Erklärung. Das Folgende ist ein Beispiel.

resp, err := http.Get(url)
defer resp.Body.Close() //Eigentlich sollte die Fehlerbeurteilung vor dem Aufschieben erfolgen

In Java wird close () oft am Ende einer Funktion geschrieben, und manchmal vergesse ich, close () zu schreiben, aber Wenn es losgeht, wird empfohlen, den Freigabeprozess sofort nach dem Erwerb der Ressource mit Defer durchzuführen.

Was bedeutet es, sofort bewertet zu werden?

Ich denke, es ist schneller, den Code tatsächlich zu betrachten. Schauen Sie sich also das folgende Beispiel an.

func main() {
    defer today()()
    fmt.Println("heute....")
}

func today() func() {
    fmt.Println("Ist es Freitag?")
    return func() {fmt.Println("Oder ist es Samstag?")}
}

Was ist, wenn Sie dies tun? Da defer am Ende von main aufgerufen wird, wird `today ...` `zuerst aufgerufen, dann` Friday in today ()? `, Endlich `oder Samstag? Sie könnten sich fragen, ob es "" sein wird.

Aber wenn ich es versuche

Ist es Freitag?
heute....
Oder ist es Samstag?

Es wird. Warum? Der Punkt ist, dass der Rückgabewert von today () funktionsfähig ist.

Das Argument des ** Aufschubaufrufs im vorherigen Abschnitt wird sofort ausgewertet, aber bitte beachten Sie den Teil **.

defer today()()Die Auswertung erfolgt im Beschreibungsteil von.(Warum gibt es zwei Klammern? Sie mögen einen Moment nachdenken, aber ich möchte es am Ende erklären, weil die Geschichte nicht stimmt.)

Damit

fmt.Println("Ist es Freitag?")

Wird ausgeführt. Fahren Sie danach mit der Hauptverarbeitung fort

fmt.Println("heute....")

Wird ausgeführt.

Dann mit verzögerter Ausführung

fmt.Println("Oder ist es Samstag?")

Es ist ein Fluss.

Warum gibt es heute zwei Klammern für die Verschiebung () ()? ??

Hat es nicht 2 Klammern? ?? Sie könnten denken, aber das ist notwendig. Was passiert, wenn Sie versuchen, eine Klammer zu verwenden?

func main() {
    defer today()
    fmt.Println("heute....")
}

func today() func() {
    fmt.Println("Ist es Freitag?")
    return func() {fmt.Println("Oder ist es Samstag?")}
}
 heute....
 Ist es Freitag?

Die Reihenfolge hat sich geändert und der Samstag ist verschwunden. .. .. ..

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

Die beiden Beschreibungen unterscheiden sich grundlegend.

1 ist der Prozess der Verschiebung, um die Heute-Funktion auszuführen. Das heißt, heute am Ende der Hauptfunktion()Wird ausgeführt. In diesem Prozess wird die anonyme Funktion zurückgegeben, aber die anonyme Funktion wird nicht ausgeführt.

Auf der anderen Seite ist 2 heute()Die zurückgegebene Funktion wird am Ende der Hauptfunktion ausgeführt. Um es leicht verständlich zu beschreiben, ist 2 eine anonyme Funktion bei der Verarbeitung von Verzögerungen.func() {fmt.Println("Oder ist es Samstag?")}Läuft.

Recommended Posts

Verstehe, wie Go's Defer funktioniert
Verstehen Sie, wie die Zabbix-API funktioniert
So funktioniert der Import von Python-Modulen
Verständnis aus dem Mechanismus Twilio # 1 - Einführung