defer
func f3() (r int) {
r = 1
defer func(r int) {
r = r + 1
fmt.Println("r=", r)
}(r)
r = 99
return
}
//返回结果:99,打印:2
func f4() (r int) {
r = 1
defer func(r *int) {
*r = *r + 1
fmt.Println("*r", *r)
}(&r)
r = 99
return
}
//返回结果:100,打印:100
通常认为defer就像真的被挪到了return之后。但defer的本质依然是函数调用。当执行到defer定义时,首先会对参数进行求值,然后参数被压入函数调用栈,此时不会进入defer函数体,而是直到函数返回时才调用defer函数体。参数被压入函数调用栈时,如果参数是值类型,那么将复制值,如果参数是指针,那么将复制指针而不是复制指针指向的值。defer函数体内的变量是在return后执行因此不受影响。因此我们在使用defer时一定要明确函数的参数类型(如果有的话),其次要明确defer函数体内的变量引用是否正确。