Verzögerte Funktionsaufrufe und Abschlusserfassung
In Go ermöglicht uns die Defer-Anweisung, eine Funktion auszuführen, kurz bevor die umgebende Funktion zurückkehrt. Ein wichtiger Aspekt von defer ist die Art und Weise, wie Schließungen behandelt werden.
In diesem Codeausschnitt:
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 } }
Teil 1 gibt einfach die Werte von i von 0 bis 4 aus. Teil 2 demonstriert dies jedoch ein interessantes Verhalten. Anstatt die erwarteten Werte von 0 bis 4 auszugeben, wird „44444“ ausgegeben.
Das liegt daran, dass der Abschluss in Teil 2 die i-Variable erfasst. Wenn der Abschluss später ausgeführt wird, hat die i-Variable den Wert, den sie in der letzten Iteration der Range-Anweisung hatte, nämlich 4. Als Ergebnis geben alle verzögerten Funktionsaufrufe 4 aus.
Im Gegensatz dazu part 3 erfasst keine äußeren Variablen. Gemäß den Go-Spezifikationen „werden bei jeder Ausführung der ‚defer‘-Anweisung der Funktionswert und die Parameter des Aufrufs wie gewohnt ausgewertet und erneut gespeichert, aber die eigentliche Funktion wird nicht aufgerufen.“ Das bedeutet, dass jeder der verzögerten Funktionsaufrufe einen anderen Wert des Parameters „n“ hat, der dem Wert von „i“ zum Zeitpunkt der Ausführung der „defer“-Anweisung entspricht.
Daher ist Teil 3 korrekt gibt „43210“ aus, da die verzögerten Funktionsaufrufe in LIFO-Reihenfolge (last-in, first-out) ausgeführt werden, bevor die umgebende Funktion zurückkehrt.
Es ist wichtig, sich den Funktionsausdruck zu merken in 'defer f()' wird zum Zeitpunkt der Ausführung der defer-Anweisung nicht ausgeführt, während der Ausdruck in 'defer f(e)' sofort ausgewertet wird.
Das obige ist der detaillierte Inhalt vonWarum gibt „defer func() { fmt.Println(i) }()' „44444' in Go aus, während „defer func(n int) { fmt.Println(n) }(i)' korrekt „43210' ausgibt? ?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!