GO中defer关键字

E度丶塔罗 · · 592 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

defer关键字在go中用于return之前执行,在golang官方文档中有说明。defer的用法类似java中的finally语句块,一般用于释放已分配的资源。
见如下例子:

package main

import (
    "io"
    "log"
)

func run(s string) (n int, err error) {
    defer func() {
        log.Printf("run(%q) = %d, %v", s, n, err)
    }()
    return 7, io.EOF
}

func main() {
    run("Go")
}

输出结果:

2019/01/31 15:13:21 run("Go") = 7, EOF

那么这个结果该如何理解呢?要使用defer时不踩坑,最重要的一点就是要明白,return xxx这一条语句并不是一条原子指令!所以总结出返回过程如下:

  • 首先执行defer之前对返回值赋值
  • 然后调用defer表达式
  • 调用return
    将上述规则改写成程序形式:
返回值 = xxx
执行 defer
直接return

按照这个方法改写上述程序:

func run(s string) (n int, err error) {
    n = 7
    err = EOF
    defer func() {
        log.Printf("run(%q) = %d, %v", s, n, err)
    }()
    return 
}

所以打印出的值是run("Go") = 7, EOF
goroutine的控制结构中,有一张表记录defer,调用runtime.deferproc时会将需要defer的表达式记录在表中,而在调用runtime.deferreturn的时候,则会依次从defer表中出栈并执行。
即多个defer调用的时候遵循后入先出原则。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:E度丶塔罗

查看原文:GO中defer关键字

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

592 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传