轨道 · 写下来的字
go defer
go defer 命名和匿名返回值函数中的返回结果不同
函数示例
package main
import "fmt"
func f1() int {
var res int
defer func() {
res++
}()
return res
}
func f2() (res int){
defer func() {
res++
}()
return res
}
func f3() (res int) {
defer func() {
res++
}()
return 1
}
func f4() (res int) {
defer func() {
res++
}()
res = 1
return res
}
func main() {
x := f1()
y := f2()
z := f3()
zz := f4()
fmt.Println("x: ", x, "y: ", y, "z: ", z, "zz: ", zz)
}
输出:
x: 0 y: 1 z: 2 zz: 2
解释说明
这里以匿名返回函数f1()作说明,执行过程如下: 首先函数返回时会自动创建一个返回变量假设为ret,函数返回时要将res赋值给ret,即有ret = res,也就是说ret=0 然后检查函数中是否有defer存在,若有则执行defer中部分,此时就到了res++ 最后返回ret 从上面过程可以看到,函数返回的是ret,即0,虽然defer中res++但是是给res做加减,res和ret是两个变量;
但是在命名返回值f2()中就会有不一样的结果,因为返回值在函数定义时以经存在,return时不需要再创建另外的变量ret,返回的ret就是res,只有一个变量,所以res++就是给实际返回的ret做加减,最终返回结果当然是1了。
f3() 等同于 f4()
defer在命名和匿名返回函数中表现不一样,这是一个很大的坑,使用中要多多注意。
← 回到文章