1 回答

TA貢獻1788條經(jīng)驗 獲得超4個贊
請參閱Defer_statements:
每次執(zhí)行“defer”語句時,調(diào)用的函數(shù)值和參數(shù)都會照常評估并重新保存,但不會調(diào)用實際函數(shù)。相反,延遲函數(shù)會在周圍函數(shù)返回之前立即調(diào)用,調(diào)用順序與延遲函數(shù)相反。也就是說,如果周圍函數(shù)通過顯式 return 語句返回,則延遲函數(shù)將在該 return 語句設置任何結(jié)果參數(shù)之后但在函數(shù)返回到其調(diào)用者之前執(zhí)行。如果延遲函數(shù)值求值為 nil,則在調(diào)用該函數(shù)時(而不是執(zhí)行“defer”語句時)會發(fā)生執(zhí)行混亂。
為了理解評估順序,讓我們嘗試一下:
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.
這樣就更漂亮了,同樣的結(jié)果,只需將所有函數(shù)替換為匿名函數(shù)即可:
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工作原理:代碼的工作
版本,內(nèi)部有足夠的文檔(注意首先評估的參數(shù)和調(diào)用將推遲到以相反順序返回的函數(shù)):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 關注
- 154 瀏覽
添加回答
舉報