golang return defer的疑惑
package main
import (
"fmt"
)
func main() {
fmt.Println(f0()) // 1
fmt.Println(f1()) // 0
}
func f0() (result int) {
defer func() {
result++
}()
return 0
}
func f1() (result int) {
result = 0 //return语句不是一条原子调用,return xxx其实是赋值+RET指令
return
}
- f0中明明返回的是0,是一个整形,虽然有个defer但是他还是一个数字0啊,为啥结果被改为了1
- f1中return那里明明啥都没有,给人直观感受就是null,他怎么就被改为了0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
go里面没有
null
。编程靠只管感受?学习新语言就好好学习这门语言的语法,思想,不要混用。问题1:defer 执行先于 return。所以会执行result++,因为你返回值定义了result变量,所以其值等于默认值0,result++等于1,只要定义了返回变量名,他会使用变量名返回,而不是你的 return 0
问题2:int默认值为0,slice,map这类复杂类型默认值才为nil
一个函数如果有命名的返回值,可以省略 return 语句的操作数,这称为裸返回。
你的代码等同于:
第一个问题: 你注释里也写了的 return不是原子操作。是先执行return后的表达式,然后先进后出的执行defer,最后才返回 因此你return 0其实是三步 1.result=0 2.result++ 3.RET
第二个问题: 虽然return后面什么都没有,但是因为你定义的是命名返回值,因此在函数签名写下的时候,你的return值就是result变量了,result变量默认值是0,且你赋值也是0,所以结果就是0。如果写成result=1那么结果就是1。如果你声明的是未命名返回值,那么你这种return后面没东西的写法是编译不通过的,如:
你的对比不全面。可以考虑把下面的几种情况一起对比下: