我遇到了一个有关“反向范围”的问题的答案],我打算对其投下反对票,因为它看起来很可笑,但经过检查就可以了(!):
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.
任何想法为什么它会这样工作?我是不是可以保证不能完全按照相反的顺序执行?另外我也不认为这是编写程序的好方法,但很想知道为什么我们会得到这个结果。
defer是LIFO或堆栈- 保证以相反的顺序执行。它获取第一个defer,并将其放在某个内部堆栈中(可能我不知道血腥的细节),然后将下一个放在该堆栈的defer顶部,然后当它到达函数末尾时,展开,开始在顶部。它看起来像是在for-loop里做的(我知道这是Go的示例,而不是您的示例),但是在其他情况下,一个功能依赖于其他功能的清理,这更有意义,为什么它应该是IS,保证执行顺序相反。
defer
LIFO
for
这是一个不同的示例,都是伪代码,但希望这一点很清楚。
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。
stream1
defer stream2 write