去:为什么延迟范围循环以相反的顺序调用? [英] Go: Why defer in range loop is called in a reverse order?

查看:210
本文介绍了去:为什么延迟范围循环以相反的顺序调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我跑过了回答关于反向范围的问题,我打算将它投下来,因为它似乎很荒谬,但经过检查,它确实有效(!):



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

 包主

导入(
fmt


func main(){
s:= [] int {1,2,3,4,5}
for i,_:= range s {
defer fmt.Println(s [i])
}
}

输出是:

  5 
4
3
2
1
已退出程序。

任何想法为何如此运作?我是否确定它不能完全按照相反的顺序执行?另外我不认为这是编写程序的好方法,但很好奇为什么我们会得到这个结果。 解决方案

code> defer 是一个 LIFO ,或一个堆栈 - 保证以相反的顺序执行。它得到第一个 defer ,并将它放在一些内部堆栈上(可能我不知道细节),然后把下一个推迟,然后当它到达函数的结尾时,它从最上面开始展开。它看起来在中为 -loop(我知道这是Go的例子,不是你的),但在其他情况下,其中一个函数依赖于其他函数的清理,它更有意义,为什么它应该是,因此,保证是逆序执行。



这是一个不同的例子,所有的伪代码,但希望

  open stream1 
延期关闭stream1
延期写入stream1stream2最好关闭,或者我们遇到麻烦......
打开stream2
推迟关闭stream2
推迟stream2这是您从stream2听到的最后一次

connect stream2到stream1

写入stream2嘿,我们在stream2中,这会馈送到stream1中

应打印如下内容:

 嘿,我们在stream2中,这会输入到stream1中
这是你从stream2听到的最后一句话
stream2最好被关闭,或者我们遇到麻烦......

如果您没有反向排序的保证,您可能无法确定 stream1 在您的延期stream2写入期间仍处于打开状态。


I've run across an answer on a question about "reverse range" and I was going to down-vote it as it seemed ridiculously wrong but checked and it actually works(!):

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])
    }
}

And the output is:

5
4
3
2
1
Program exited.

Any ideas why it works this way? Am I right it's not guaranteed to be executed exactly in the reverse order? Also I don't think it's a good way to write programs but curious to find why are we getting this result.

解决方案

defer is a LIFO, or a stack - it is guaranteed to executed in reverse order. It gets the first defer and puts it on some internal stack (probably, I don't know the gory details), and then puts the next defer on top of that one, and then when it hits the end of the function, it unwinds, starting at the top. It seems contrived in a for-loop (I know this is Go's example, not yours), but in other cases where one function depends upon the clean-up of some other function, it makes more sense why it SHOULD be, and hence IS, guaranteed to be reverse order of execution.

Here's a different example, all pseudo-code, but hopefully the point is clear.

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"

Should print something like:

"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..."

If you didn't have guarantees about reverse ordering, you couldn't be sure stream1 was still open during your defer stream2 write.

这篇关于去:为什么延迟范围循环以相反的顺序调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆