Go返回值return与defer的坑
Posted 神神的蜗牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go返回值return与defer的坑相关的知识,希望对你有一定的参考价值。
func TestDefer() int
v := 1
defer func()
v++
fmt.Println(`defer v:`, v)
()
v = 3
return v
func TestDefer2() (v int)
v = 1
defer func()
v++
fmt.Println(`defer2 v:`, v)
()
v = 3
return
func TestDefer3() (v int)
v = 1
defer func()
v++
fmt.Println(`defer3 v:`, v)
()
v = 3
vv := v+1
fmt.Println(`vv:`, vv)
return vv
func main()
fmt.Println(`TestDefer:`, TestDefer())
fmt.Println(`TestDefer2:`, TestDefer2())
fmt.Println(`TestDefer3:`, TestDefer3())
上面三种方法的输出结果:
defer v: 4
TestDefer: 3
defer2 v: 4
TestDefer2: 4
vv: 4
defer3 v: 5
TestDefer3: 5
三种例子的主要区别是返回值的初始化方式不同:
以参数形式定义返回值变量名称:则实际返回结果是在 defer 处理后的结果。
在函数内定义的变量作为返回值时,defer 不会影响最终返回结果
当我们在函数定义的时候申明了返回值类型与变量名时,函数内部直接使用 return
即可,而当返回值并没有申明变量名时,内部会自动定一个变量名,因此函数内部的 return v
并不是我们认为的 v 而是被替换了
常见的在函数内定义返回值时,内部实际执行的顺序:
# 参考上面例子1 TestDefer() int
v := 1
v = 3
# 系统内部给返回值类型 int 自动生成了变量 a 并将我们原来的 return v 中的 v 赋值给 a 返回 a
a := v
# 此时 defer 中的 v 已经和返回值没有关系了
func()
v++
fmt.Println(`defer v:`, v)
()
return a
等同于下面例子
# 我们定义是这样的
func TestDefer() int
v := 1
return v
# 实际等同于这样的效果
func TestDefer() (a int)
v := 1
a = v
return
以参数形式定义返回值时,内部实际执行的顺序:
# 参考上面例子3 TestDefer3() (v int)
v = 1
v = 3
vv := v+1
# 这里系统内部自动将我们原来的 return vv 进行赋值给自定义的返回值类型 int 对应的变量 v
v = vv
# defer 中的 v 与返回值从始至终都是同一个变量, v 执行了自增并被返回
func()
v++
fmt.Println(`defer3 v:`, v)
()
return
以上是关于Go返回值return与defer的坑的主要内容,如果未能解决你的问题,请参考以下文章
Go ---- defer 和 return 执行的先后顺序