分享
  1. 首页
  2. 文章

defer的执行顺序与时机

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

我们知道defer会在函数结束时执行,那么首先思考两个问题:

  1. 如果有多个defer,执行顺序是怎样的?
  2. defer是在return之前还是之后执行的?如果defer执行的内容对返回值进行了修改,return结果是否会改变?

多个defer的执行顺序

通过下面这个个例子,我们看下defer的执行顺序:

package main
import (
 "fmt"
)
func main() {
 defer fmt.Println("main defer1")
 test()
 defer fmt.Println("main defer2")
}
func test() () {
 defer func() {
 fmt.Println("test defer1")
 }()
 defer func() {
 fmt.Println("test defer2")
 }()
}

执行结果为:

test defer2
test defer1
main defer2
main defer1

我们发现defer就像一个LIFO的栈,后defer的会先执行,且在函数退出时才会执行。

defer与return的执行顺序

首先看个例子:

package main
import (
 "fmt"
)
func main() {
 ret := test()
 fmt.Println("test return:", ret)
}
func test() ( int) {
 var i int
 defer func() {
 i++ //defer里面对i增1
 fmt.Println("test defer, i = ", i)
 }()
 return i
}

执行结果为:

test defer, i = 1
test return: 0

test函数的返回值为0,defer里面的i++操作好像对返回值并没有什么影响。
这是否表示"return i"执行结束以后才执行defer呢?
非也!再看下面的例子:

package main
import (
 "fmt"
)
func main() {
 ret := test()
 fmt.Println("test return:", ret)
}
//返回值改为命名返回值
func test() (i int) {
 //var i int
 defer func() {
 i++
 fmt.Println("test defer, i = ", i)
 }()
 return i
}

执行结果为:

test defer, i = 1
test return: 1

这次test函数的返回值变成了1,defer里面的"i++"修改了返回值。所以defer的执行时机应该是return之后,且返回值返回给调用方之前。
至于第一个例子中test函数返回值不是1的原因,还涉及到函数匿名返回值与命名返回值的差异,以后再单独分析。

结论

  1. defer的执行顺序为:后defer的先执行。
  2. defer的执行顺序在return之后,但是在返回值返回给调用方之前,所以使用defer可以达到修改返回值的目的。

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

本文来自:Segmentfault

感谢作者:moonbamboo

查看原文:defer的执行顺序与时机

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

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

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏