Heim >Backend-Entwicklung >Golang >Wie geht die „defer'-Anweisung von Go mit der Variablenauswertung um und welche Problemumgehungen gibt es für unerwartetes Verhalten?
Beim Aufschieben einer Funktionsausführung in Go ist es wichtig, das Auswertungsverhalten zu verstehen. Wie in der Spezifikation angegeben, werden die Parameter und der Wert der Funktion sofort ausgewertet, wenn die Defer-Anweisung auftritt. Dies kann zu unerwarteten Ergebnissen führen, insbesondere wenn „defer“ mit Variablen verwendet wird, die innerhalb der Funktion geändert werden.
Betrachten Sie die folgende Funktion:
func printNumbers() { var x int defer fmt.Println(x) for i := 0; i < 5; i++ { x++ } }
Die Die Absicht dieser Funktion besteht darin, den Endwert von x (5) auszugeben, wenn die Funktionsausführung endet. Aufgrund der sofortigen Auswertung von x während der Defer-Anweisung wird jedoch stattdessen Null gedruckt.
Um dieses Problem zu beheben, gibt es mehrere alternative Lösungen:
1. Anonyme Funktion:
Anstatt die ursprüngliche Funktion aufzuschieben, erstellen Sie eine anonyme Funktion, die den aktuellen Wert von x erfasst und ausgibt.
func printNumbers() { var x int defer func() { fmt.Println(x) }() for i := 0; i < 5; i++ { x++ } }
2. Zeiger:
Verwenden Sie einen Zeiger auf x, um den tatsächlichen Wert zu verschieben. Da bei der Defer-Anweisung nur die Adresse ausgewertet wird, wird der Endwert von x gedruckt.
func printNumbers() { var x int defer fmt.Println(&x) for i := 0; i < 5; i++ { x++ } } func Print(i *int) { fmt.Println(*i) }
3. Benutzerdefinierter Typ:
Erstellen Sie einen benutzerdefinierten Typ, der fmt.Stringer implementiert. Dadurch kann der Typ definieren, wie er gedruckt werden soll, um sicherzustellen, dass der richtige Wert angezeigt wird.
type MyInt int func (m *MyInt) String() string { return strconv.Itoa(int(*m)) } func printNumbers() { var x MyInt defer fmt.Println(&x) for i := 0; i < 5; i++ { x++ } }
4. Slices:
Slices sind Deskriptoren, die auf die zugrunde liegende Datenstruktur verweisen. Durch das Zurückstellen eines Slice, das die Variable enthält, wird der endgültige geänderte Wert gedruckt.
func printNumbers() { x := []int{0} defer fmt.Println(x) for i := 0; i < 5; i++ { x[0]++ } }
Das Verständnis des unmittelbaren Auswertungsverhaltens verzögerter Funktionsausführungen ist für die effektive Verwendung von defer von entscheidender Bedeutung. Die bereitgestellten Lösungen zeigen verschiedene Ansätze, um sicherzustellen, dass die beabsichtigten Werte gedruckt werden, wenn die Ausführung einer Funktion verzögert wird.
Das obige ist der detaillierte Inhalt vonWie geht die „defer'-Anweisung von Go mit der Variablenauswertung um und welche Problemumgehungen gibt es für unerwartetes Verhalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!