defer&命名返回值和非命名返回值的区别
结论
首先 return
非原子返回的这个结论之前已经说过了,然后我们看下在使用 defer
对返回值进行修改时,针对命名返回值和非命名返回值,有啥不同,先说结论
- 命名返回值本质上是函数作用域内的一个变量,defer 可以修改它;而非命名返回值是通过值复制的方式传出,defer 修改不了。
名词解释
- 函数的栈帧(stack frame)是函数在运行时在栈(stack)上分配的一块内存,用来保存:参数,返回值,局部变量,返回地址,可能还有调用者的一些上下文信息(如寄存器、defer 信息等)
解释
通俗来讲,就是变量的作用域不一致,可以理解为,🎯 有没有一个“命名的栈变量”供 defer 修改
命名返回值就是一个在函数作用域里声明的变量,会在栈帧中提前分配空间,defer defer 可以直接访问和修改它。重点:函数有命名返回值 result,这个返回值会被存储在栈帧中。Go 会为 result 分配一个局部变量,并将其初始化为零值(在下面个例子中是 int 类型,初始化值为 0)。
非命名返回值是一个匿名的 返回值槽
,return 时只是把局部变量的值复制进去,defer 修改不了。
示例
- 示例1
1 | package main |
- 示例2
1 | package main |
🌟 什么是“返回值槽”?
- 可以理解成:函数在返回之前,把值放进一个“临时的传送带槽位”里,调用者会从这个槽中取回返回值。
非命名返回值,这个“槽”只是个临时复制品,defer 改不了。
命名返回值,这个“槽”就是函数作用域内的变量,defer 可以改它。
示例
接下来我们引入返回值槽的概念,对上面两个函数做进一步拆解
示例1
1 | package main |
- 示例2
流程图

1 | package main |