Go 彻底弄懂return和defer的微妙关系
package main
import "fmt"
func main() {
fmt.Println("f1 result: ", f1())
fmt.Println("f2 result: ", f2())
}
func f1() int {
var i int
defer func() {
i++
fmt.Println("f11: ", i)
}()
i = 1000
return i
}
func f2() (i int) {
defer func() {
i++
fmt.Println("f21: ", i)
}()
i = 1000
return i
}
f1函数:
进入该函数,因为没有指定返回值变量,需要先声明i变量,因为是int类型,如果没有赋值,该变量初始化值为0,之后执行i=1000的赋值操作,然后执行return语句,返回i的值。
真正返回之前还要执行defer函数部分,返回1000
f2函数:
进入该函数,因为已经定义好了返回值变量即为i,然后直接赋值i=1000,再返回i的值。
同样的,也要在真正返回i前,执行defer函数,同样i依次自增得到1001
问题的关键是为什么无名参数返回的值是1000,其并未收到defer函数对于i自增的影响;而有名函数在执行defer后,最后返回的i值为1001。
原因就是return会将返回值先保存起来,对于无名返回值来说,
保存在一个临时对象中,defer是看不到这个临时对象的;
而对于有名返回值来说,就保存在已命名的变量中。