go语言-defer关键字
来源:互联网 发布:小米4c可以4g网络吗 编辑:程序博客网 时间:2024/05/17 02:35
example1func f() (result int) { defer func() { result++ }() return 0}example2func f() (r int) { t := 5 defer func() { t = t + 5 }() return t}example3func f() (r int) { defer func(r int) { r = r + 5 }(r) return 1}
首先要明确的是:defer是在return之前执行的。这个在 官方文档中明确说明了的。然后是了解defer的实现方式,大致就是在defer出现的地方,插入指令CALL runtime.deferproc,然后在函数返回之前的地方,插入指令CALL runtime.deferreturn。为了支持多值返回,go是用栈返回值的
return xxx这一条语句并不是一条原子指令!
整个return过程,没有defer之前,先在栈中写一个值,这个值会被当作返回值,然后再调用RET指令返回。return xxx语句汇编后是先给返回值赋值,再做一个空的return,( 赋值指令 + RET指令)。defer的执行是被插入到return指令之前的,有了defer之后,就变成了(赋值指令 + CALL defer指令 + RET指令)。而在CALL defer函数中,有可能将最终的返回值改写了…也有可能没改写。总之,如果改写了,那么看上去就像defer是在return xxx之后执行的~
上面的基础知识都有了,然后就可以说说神奇的defer了。告诉大家一个简单的转换规则大家就再也不为defer迷糊了。改写规则是将return语句分开成两句写,return xxx会被改写成:
返回值 = xxx
调用defer函数
空的return
先看example1,它可以改写成这样:func f() (result int) { result = 0 //return语句不是一条原子调用,return xxx其实是赋值+RET指令 func() { //defer被插入到return之前执行,也就是赋返回值和RET指令之间 result++ }() return}所以这个返回值是1。再看example2,它可以改写成这样:func f() (r int) { t := 5 r = t //赋值指令 func() {//defer被插入到赋值与返回之间执行,这个例子中返回值r没被修改过 t = t + 5 } return //空的return指令}所以这个的结果是5。最后看example3,它改写后变成:func f() (r int) { r = 1 //给返回值赋值 func(r int) { //这里改的r是传值传进去的r,不会改变要返回的那个r值 r = r + 5 }(r) return //空的return}所以这个例子的结果是1。
再看一个例子
func do() (ok bool) { file,_ := os.Open("c:\a.txt") defer file.Close() // doSomething return ok}
我们可以在官方的文档中看到defer的执行顺序是逆序的,也就是先进后出的顺序:
for i := 0; i < 5; i++ { defer fmt.Printf("%d ", i)}
打印结果是:4,3,2,1,0
阅读全文
0 0
- go语言-defer关键字
- Go语言中的defer关键字
- 关于Go语言中defer关键字
- go defer关键字
- go语言defer使用
- go语言defer使用
- go语言defer使用 .
- Go语言之defer
- Go语言defer
- Go语言defer的使用
- go语言 golang defer 关注点
- go语言defer的用法
- Go语言defer学习小结
- GO语言defer延迟代码
- 关于Go关键字defer的一些坑
- go语言, defer con.Close() 使用之一
- Go语言优雅设计之-defer(延迟)
- go语言defer执行时机简单分析
- 安装percona 5.7
- 史上最强Java学习路线(详解)
- opc-ua技术资料网站汇总
- MapReduce运行全流程
- 投区块链?听听当下硅谷最火的四条投资军规
- go语言-defer关键字
- 微信页面禁止长按复制(input输入框可正常输入)
- caffe入门学习(5):绘制网络结构图
- Python之路【第十七篇】:Django【进阶篇 】
- 在腾讯云上部署项目
- Tomcat项目运行时加载web项目的顺序
- 写接口时,对数据进行验证
- Linux Tomcat启动/停止服务并同时查看日志log
- [shell]shell快速入门教程