在学习golang defer,了解到defer会在函数体生命周期最后来执行。并且是压栈的形式,即先进后出。
package main
import "fmt"
func deferFunc() int {
fmt.Println("deferFunc is calling")
return 0
}
func returnFunc() int {
fmt.Println("returnFunc is calling")
return 0
}
func deferAndReturn() int {
fmt.Println("deferAndReturn is calling")
defer deferFunc() //defer最后执行
return returnFunc()
}
func main() {
defer fmt.Println("defer a is calling") //会最后执行
defer fmt.Println("defer b is calling") //这个会把a压到箱底(压栈),所以先执行
fmt.Println("main is calling")
deferAndReturn()
}
执行的结果是
main is calling
deferAndReturn is calling
returnFunc is calling
deferFunc is calling
defer b is calling
defer a is calling
同时做以下练习
package main
import "fmt"
func returnFun(i int) int {
fmt.Println("return时i的值是:", i)
return i
}
func testFun(i int) int {
defer func() {
i++
fmt.Println("defer时i的值是:", i)
}()
return returnFun(i)
}
func main() {
fmt.Println("执行结果是:", testFun(1))
}
返回结果:
return时i的值是: 1
defer时i的值是: 2
执行结果是: 1
可见,defer确实是在return之后才执行。
可以再做一个比较有意思的实验
package main
import "fmt"
func returnFun(i int) int {
fmt.Println("return时i的值是:", i)
return i
}
func testFun() (i int) {
defer func() {
i++
fmt.Println("defer时i的值是:", i)
}()
return returnFun(i)
}
func main() {
fmt.Println("执行结果是:", testFun())
}
我们为 testFun 指定返回值为 i 得出的结果是:
return时i的值是: 0
defer时i的值是: 1
执行结果是: 1
发现go是执行到return关键字的时候给返回值i赋值(此时函数/方法并未结束执行),然后执行defer关键字时又改写了返回值。所以得到以上输出结果。