1 回答

TA貢獻1788條經驗 獲得超4個贊
請參閱Defer_statements:
每次執行“defer”語句時,調用的函數值和參數都會照常評估并重新保存,但不會調用實際函數。相反,延遲函數會在周圍函數返回之前立即調用,調用順序與延遲函數相反。也就是說,如果周圍函數通過顯式 return 語句返回,則延遲函數將在該 return 語句設置任何結果參數之后但在函數返回到其調用者之前執行。如果延遲函數值求值為 nil,則在調用該函數時(而不是執行“defer”語句時)會發生執行混亂。
為了理解評估順序,讓我們嘗試一下:
defer having()(fun("with Go."))
讓我們運行它并閱讀評估順序的代碼注釋:
package main
import "fmt"
func main() {
? ? defer having()(fun("with Go."))
? ? fmt.Print("some ") // evaluation order: 3
}
func having() func(string) {
? ? fmt.Print("Go ") // evaluation order: 1
? ? return funWithGo
}
func fun(msg string) string {
? ? fmt.Print("have ") // evaluation order: 2
? ? return msg
}
func funWithGo(msg string) {
? ? fmt.Println("fun", msg) // evaluation order: 4
}
輸出:
Go have some fun with Go.
這樣就更漂亮了,同樣的結果,只需將所有函數替換為匿名函數即可:
package main
import "fmt"
func main() {
? ? defer func() func(string) {
? ? ? ? fmt.Print("Go ") // evaluation order: 1
? ? ? ? return func(msg string) {
? ? ? ? ? ? fmt.Println("fun", msg) // evaluation order: 4
? ? ? ? }
? ? }()(func(msg string) string {
? ? ? ? fmt.Print("have ") // evaluation order: 2
? ? ? ? return msg
? ? }("with Go."))
? ? fmt.Print("some ") // evaluation order: 3
}
我希望這可以幫助您了解其defer工作原理:代碼的工作
版本,內部有足夠的文檔(注意首先評估的參數和調用將推遲到以相反順序返回的函數):deferfmt.Println
package main
import "fmt"
func printTicket(age int) float64 {
? ? fmt.Println("...order is 2...")
? ? switch {
? ? case age <= 13:
? ? ? ? return 9.99
? ? case age > 13 && age < 65:
? ? ? ? return 19.99
? ? default:
? ? ? ? return 12.99
? ? }
}
func main() {
? ? age := 999
? ? defer fmt.Println("...order is 4...Your age is:", getAge(&age))
? ? defer fmt.Println("...order is 3...Your ticket price is:", printTicket(age))
}
func getAge(age *int) int {
? ? fmt.Println("...order is 1...")
? ? fmt.Print("Enter age=")
? ? fmt.Scanln(age)
? ? return *age
}
輸出:
...order is 1...
Enter age=999
...order is 2...
...order is 3...Your ticket price is: 12.99
...order is 4...Your age is: 999
- 1 回答
- 0 關注
- 144 瀏覽
添加回答
舉報