我在一个关于"反向范围"的问题上遇到了一个答案,我打算对它进行投票,因为它看起来很荒谬,但是检查了它确实有效(!):
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])
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
5
4
3
2
1
Program exited.
Run Code Online (Sandbox Code Playgroud)
任何想法为什么这样工作?我是对的,不能保证完全以相反的顺序执行吗?此外,我不认为这是编写程序的好方法,但很想知道为什么我们得到这个结果.
defer
是一个LIFO
或一个堆栈 - 它保证以相反的顺序执行.它得到第一个defer
并将它放在一些内部堆栈上(可能,我不知道血腥细节),然后将下一个defer
放在那个上面,然后当它到达函数的末尾时,它展开,开始在顶部.它似乎是在for
-loop中设计的(我知道这是Go的例子,不是你的),但在其他情况下,一个函数依赖于其他函数的清理,它更有意义为什么它应该是,因此,IS,保证是相反的执行顺序.
这是一个不同的例子,所有的伪代码,但希望这一点很清楚.
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"
Run Code Online (Sandbox Code Playgroud)
应该打印像:
"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..."
Run Code Online (Sandbox Code Playgroud)
如果您没有关于逆向订购的保证,您可能无法确定stream1
在您的期间是否仍处于打开状态defer stream2 write
.
归档时间: |
|
查看次数: |
776 次 |
最近记录: |