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

我遇到了一个关于“反向范围”的问题的答案,我打算否决它,因为它看起来非常错误但经过检查并且它确实有效(!):


https://play.golang.org/p/4K2fDlSoCm


package main


import (

    "fmt"

)


func main() {

    s := []int{1, 2, 3, 4, 5}

    for i, _ := range s {

        defer fmt.Println(s[i])

    }

}

输出是:


5

4

3

2

1

Program exited.

任何想法为什么它会以这种方式工作?我是对的,它不能保证完全按照相反的顺序执行吗?此外,我认为这不是编写程序的好方法,但很想知道为什么我们会得到这个结果。


凤凰求蛊
浏览 134回答 1
1回答

慕森王

defer是 aLIFO或堆栈 - 保证以相反的顺序执行。它获取第一个defer并将其放在某个内部堆栈(可能,我不知道血淋淋的细节),然后将下一个defer放在那个之上,然后当它到达函数的末尾时,它展开,开始在顶部。它似乎是在一个for-loop 中设计的(我知道这是 Go 的示例,而不是您的示例),但在其他情况下,一个函数依赖于其他函数的清理,为什么它应该是更有意义的,因此是,保证是相反的执行顺序。这是一个不同的示例,所有伪代码,但希望这一点很清楚。open stream1defer close stream1defer write stream1 "stream2 better be closed, or we are in trouble..."open stream2defer close stream2defer stream2 "this is the last you'll ever hear from stream2"connect stream2 to stream1write 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.
打开App,查看更多内容
随时随地看视频慕课网APP