dshakcsq64956 2018-10-09 09:53

# golang defer语句是在return语句之前还是之后执行？

I have a question about golang defer: Is golang defer statement execute before or after return statement?

``````func test1() (x int) {
defer fmt.Printf("in defer: x = %d
", x)

x = 7
return 9
}

func test2() (x int) {
defer func() {
fmt.Printf("in defer: x = %d
", x)
}()

x = 7
return 9
}

func test3() (x int) {
x = 7
defer fmt.Printf("in defer: x = %d
", x)
return 9
}

func main() {
fmt.Println("test1")
fmt.Printf("in main: x = %d
", test1())
fmt.Println("test2")
fmt.Printf("in main: x = %d
", test2())
fmt.Println("test3")
fmt.Printf("in main: x = %d
", test3())
}
``````

In `test1()`, using `Printf`to print x after defer. In `test2()`, using a anonymous function to print x after defer. In `test3()`, using `Printf`to print x after defer, but defer after `x = 7`.

But the result is:

``````test1
in defer: x = 0
in main: x = 9
test2
in defer: x = 9
in main: x = 9
test3
in defer: x = 7
in main: x = 9
``````

So, is any one can explain: 1. why got this result? why test1 prints 0, test2 print9, test3 prints 7. 2. is defer statement excutes after return or before return?

Thanks a lot.

• 写回答

#### 4条回答默认 最新

• douxianwu2221 2018-11-09 04:37
关注

Thanks @dev.bmax @Tranvu Xuannhat @rb16. With your help, I found the key explanation from Defer_statements.

Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked.

We can break up `defer ...` into three parts.

1. invoke defer, evaluating the value of function parameter.
2. execute defer, pushing a function in to stack.
3. execute functions in stack after return or panic.

I made a new test4 to explain.

``````func test4() (x int) {
defer func(n int) {
fmt.Printf("in defer x as parameter: x = %d
", n)
fmt.Printf("in defer x after return: x = %d
", x)
}(x)

x = 7
return 9
}
``````

In test4,

1. invoke defer, evaluating the value of n, n = x = 0, so x as parameter is 0.
2. execute defer, pushing `func(n int)(0)` onto stack.
3. execute `func(n int)(0)` after `return 9`, n in ```fmt.Printf("in defer x as parameter: x = %d ", n)``` has been evaluated, x in ```fmt.Printf("in defer x after return: x = %d ", x)``` will be evaluated now, x is 9。

So, got the result:

``````test4
in defer x as parameter: x = 0
in defer x after return: x = 9
in main: x = 9
``````
本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

#### 悬赏问题

• ¥50 使用 java+selenium 接管手动打开的IE浏览器
• ¥15 ios 新安装app收不到fcm推送
• ¥15 有没有实力的写手？有过成品的优先
• ¥15 图像信息库的建立与识别
• ¥15 韩国网站购物，KG支付的支付回调如何解决
• ¥15 workstation导入ovf文件，报错，怎么解决呢？
• ¥15 关于#c语言#的问题：构成555单稳态触发器，采用LED指示灯延时时间，对延时时间进行测量并显示（如楼道声控延时灯）需要Proteus仿真图和C语言代码
• ¥15 workstation加载centos进入emergency模式，查看日志报警如图，怎样解决呢？
• ¥50 如何用单纯形法寻优不能精准找不到给定的参数，并联机构误差识别，给定误差有7个？matlab
• ¥15 workstation加载centos进入emergency模式，查看日志报警如图，没有XFS,怎样解决呢？