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 关注
- 108 浏览
添加回答
举报