Heim  >  Artikel  >  Backend-Entwicklung  >  Warum führt das Aufschieben der Schließungserfassung in Go zu unerwartetem Verhalten?

Warum führt das Aufschieben der Schließungserfassung in Go zu unerwartetem Verhalten?

Linda Hamilton
Linda HamiltonOriginal
2024-11-10 19:35:02452Durchsuche

Why Does Deferring Closure Capture in Go Lead to Unexpected Behavior?

Abschlusserfassung in Go verzögern

Die Defer-Anweisung von Go kann verwendet werden, um eine Funktion auszuführen, nachdem die umgebende Funktion zurückgegeben wurde. Bei der Verwendung mit Abschlüssen ist es jedoch wichtig zu verstehen, wie die Parametererfassung funktioniert.

Das Problem

Beachten Sie den folgenden Code:

package main

import "fmt"

func main() {
    var whatever [5]struct{}

    for i := range whatever {
        fmt.Println(i)
    } // part 1

    for i := range whatever {
        defer func() { fmt.Println(i) }()
    } // part 2

    for i := range whatever {
        defer func(n int) { fmt.Println(n) }(i)
    } // part 3
}

Die Ausgabe des Codes ist:

0
1
2
3
4
4
3
2
1
0
4
4
4
4
4

Analyse

  • Teil 1: Druckt den Schleifenzähler i wie erwartet.
  • Teil 2: Erfasst die Variable i im Abschluss. Wenn der Abschluss jedoch ausgeführt wird, hat i den Wert aus der letzten Iteration der Schleife, der 4 ist. Daher wird „44444“ ausgegeben.
  • Teil 3: Wird nicht erfasst alle äußeren Variablen. Der Abschluss wird ausgewertet, wenn die Defer-Anweisung ausgeführt wird, sodass jeder Defer-Aufruf einen anderen Wert von n hat, was zu „43210“ führt.

Hauptunterschiede

Der entscheidende Unterschied zwischen Teil 2 und 3 besteht darin, ob der Abschluss äußere Variablen erfasst oder nicht. In Teil 2 erfasst der Abschluss i, was eine Referenz auf eine äußere Variable ist. In Teil 3 hat der Abschluss keine äußeren Referenzen, sodass jeder Aufruf einen anderen Wert von n hat.

Zusätzliche Überlegungen

  • Verzögerte Aufrufe sind Wird in der LIFO-Reihenfolge (Last-In-First-Out) ausgeführt, bevor die umgebende Funktion zurückkehrt.
  • Der Ausdruck wird ausgewertet, wenn die Defer-Anweisung ausgeführt wird, nicht der Funktion selbst.

Das obige ist der detaillierte Inhalt vonWarum führt das Aufschieben der Schließungserfassung in Go zu unerwartetem Verhalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn