golang的defer详解
来源:互联网 发布:可以编辑照片的软件 编辑:程序博客网 时间:2024/06/05 01:12
###代码
先阅读一下代码,然后给出答案,之后在运行,看看结果是否一致,如果一致,不用往下看了,你已经懂defer了package mainfunc main() { println(example1(1)) println(example2(1)) println(example3(1)) println(example4()) println(example5()) println(example6())}func example1(i int) (t int) { t = i defer func() { t += 3 }() return t}func example2(i int) int { t := i defer func() { t += 3 } return t}func example3(i int) (t int) { defer func() { t += i }() return 2}func example4() (result int) { defer func() { result++ }() return 0}func example5() int { t := 5 defer func() { t = t + 5 }() return t}func example6() (r int) { defer func(r int) { r = r + 5 }(r) return 1}
解析
首先您觉得是defer和return哪个先执行呢?首先要明确的是:defer是在return之前执行的这是官方文档中明确说明的http://golang.org/ref/spec#Defer_statements ,知道就行了,可以无视整个return过程,没有defer之前是,先把在栈中写一个值,这个值被会当作返回值。然后再调用RET指令返回。return xxx语句汇编后是先给返回值赋值,再做一个空的return: ( 赋值指令 + RET指令)defer的执行是被插入到return指令之前的有了defer之后,就变成了 (赋值指令 + CALL defer指令 + RET指令)上面这几句话是从别的地方贴过来的。也就是说:看完之后来一一解释一下上面的几个函数(1)先在栈中写一个值,这个值被当做返回值; (2)然后调用空的return语句。(3)需要注意的是看defer func里面修改的是返回的变量还是修改的别的变量,这里容易理解错误,例如example2example1 函数返回值t作用域为整个函数,在return之前defer会被执行,所以t会被修改,返回4;example2 可以写成下面这样,首先给x赋值=1,defer修改t的值=4,但是不修改x最终结果仍然为1;func example2(i int) x int {t := idefer func() { t += 3}return t}example3 修改为下面这样写就方便理解了,返回3;func example3(i int) (t int) { t = 2 defer func() { t += i }() return}example4 同example3,返回1example5 修改一下代码写成下边这样;defer func修改的不是r,返回5;func example5() (r int) {t := 5defer func() { t = t + 6}()fmt.Println(t)return t}example6 defer执行的func传入的参数相当于赋值,不会改变原来的值,返回1;
如果有不对的理解欢迎批评指出。
阅读全文
0 0
- golang的defer详解
- golang中defer的详解
- golang中defer的执行
- Golang有多个defer的情况
- golang-defer坑的本质
- golang defer
- Golang defer 使用时的坑
- golang 使用defer、panic、recover的问题
- golang中defer精析
- golang之defer
- golang之defer
- golang之defer
- golang defer 功能说明
- golang defer讲解
- 关于golang的defer、 return、返回值三者的执行逻辑
- Go实战--golang中defer的使用(有事没事defer一下)
- C++11实现golang的defer类似Java finally操作。
- golang defer 语句匿名函数和具名函数的区别
- 关于Vue实例的生命周期各状态函数(钩子)说明
- yii初始化控制器的两种方法
- Vim编辑器-批量注释与反注释
- java 常用集合list与Set、Map区别及适用场景总结
- 往新建的泛型集合List<T>中添加对象
- golang的defer详解
- 应用最广的模式-单列模式(结合Android源码)
- 修复 Ubuntu 中“Unable to lock the administration directory (/var/lib/dpkg/)”的
- Linux进程间通信方式
- 数据操作
- GROUP BY分组查询与SQL执行顺序
- 第一篇博客,处女作
- Android 不让EditText自动获取焦点
- jsp通过<img>标签的src属性来调用servlet类生成验证码遇到的问题