为了账号安全,请及时绑定邮箱和手机立即绑定

为什么以相反的顺序调用范围循环中的延迟?

为什么以相反的顺序调用范围循环中的延迟?

Go
凤凰求蛊 2022-01-10 11:00:08
我遇到了一个关于“反向范围”的问题的答案,我打算否决它,因为它看起来非常错误但经过检查并且它确实有效(!):https://play.golang.org/p/4K2fDlSoCmpackage mainimport (    "fmt")func main() {    s := []int{1, 2, 3, 4, 5}    for i, _ := range s {        defer fmt.Println(s[i])    }}输出是:54321Program exited.任何想法为什么它会以这种方式工作?我是对的,它不能保证完全按照相反的顺序执行吗?此外,我认为这不是编写程序的好方法,但很想知道为什么我们会得到这个结果。
查看完整描述

1 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

defer是 aLIFO或堆栈 - 保证以相反的顺序执行。它获取第一个defer并将其放在某个内部堆栈(可能,我不知道血淋淋的细节),然后将下一个defer放在那个之上,然后当它到达函数的末尾时,它展开,开始在顶部。它似乎是在一个for-loop 中设计的(我知道这是 Go 的示例,而不是您的示例),但在其他情况下,一个函数依赖于其他函数的清理,为什么它应该是更有意义的,因此是,保证是相反的执行顺序。


这是一个不同的示例,所有伪代码,但希望这一点很清楚。


open stream1

defer close stream1

defer write stream1 "stream2 better be closed, or we are in trouble..."

open stream2

defer close stream2

defer stream2 "this is the last you'll ever hear from stream2"


connect stream2 to stream1


write stream2 "hey, we are in stream2, this feeds into stream1"

应该打印如下内容:


"hey, we are in stream2, this feeds into stream1"

"this is the last you'll ever hear from stream2"

"stream2 better be closed, or we are in trouble..."

如果您没有关于反向排序的保证,您无法确定stream1在您的defer stream2 write.


查看完整回答
反对 回复 2022-01-10
  • 1 回答
  • 0 关注
  • 133 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信