返回信息流func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
a := 1
b := 2
defer calc("1", a, calc("10", a, b))
a = 0
defer calc("2", a, calc("20", a, b))
b = 1
}
像这个里面,defer的4个函数的顺序为什么是2,4,3,1呢?(从上到下,从左到右)
这是一条镜像帖。来源:北邮人论坛 / golang / #1209同步于 2018/9/23
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖
golang中defer的顺序感觉还是有点没搞懂?
erjiguan
2018/9/23镜像同步9 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
那这里第二个calc为什么是最后入栈的呢
【 在 nitroethane 的大作中提到: 】
: 多个 defer 的调用采用的是类似于栈的操作模式,后进先出的模式。
不知道我理解的顺序是否是你期望的。我认为是先执行 cacl(“2”),从而导致执行 cacl(“20”),然后执行 1 和 10
【 在 erjiguan (二极管) 的大作中提到: 】
: 那这里第二个calc为什么是最后入栈的呢
我试过了,是我上面写的顺序
【 在 nitroethane (nitroethane) 的大作中提到: 】
: 不知道我理解的顺序是否是你期望的。我认为是先执行 cacl(“2”),从而导致执行 cacl(“20”),然后执行 1 和 10
我刚 debug 了下这段代码,当 main 函数执行到第一个 defer 时,先去执行了 `calc("10", a, b)`,然后跳到 main 函数继续往下走;到第二个 defer 时也是这样,先执行 `calc("20", a, b"`,然后跳到 main 函数直到 main 函数末尾,最后再执行 `calc("2", a, b)` 和 `calc("1", a, b)`。
根据此结果做点小小的猜测:defer 要求跟在其后的函数参数必须是确定的,即如果参数是一个函数,那么执行这个函数并将其返回值作为参数。如果还是要问为什么,得去看 golang 中 defer 的具体实现了。
【 在 erjiguan 的大作中提到: 】
: 我试过了,是我上面写的顺序
关于defer,除了LIFO的顺序之外,还有就是参数是在声明defer时就会解析的。
如果不明白的话,认真看这个例子:https://golang.org/doc/effective_go.html#defer
```We can do better by exploiting the fact that arguments to deferred functions are evaluated when the defer executes. ```