我不明白,为什么这个程序打印421
而不是431
?
package main
import "fmt"
var x int
func f() int {
x++
return x
}
func main() {
o := fmt.Println
defer o(f())
defer func() {
defer o(recover())
o(f())
}()
defer f()
defer recover()
panic(f())
}
下面我添加了评论如何我猜:
package main
import "fmt"
var x int
func f() int {
x++
return x
}
func main() {
o := fmt.Println
defer o(f()) // x=1
defer func() {
defer o(recover()) // x=3 from panic (but if we ll execute this program we ll see 2)
o(f()) // x=4
}()
defer f() // x=2
defer recover() //nil
panic(f()) // x=3
}
1条答案
按热度按时间3zwjbxry1#
defer
不调用该函数,但它确实“立即”计算其参数。此外,如果从延迟函数调用recover()
,则对recover()
的调用仅停止死机状态(defer recover()
不符合此条件)。请参阅为什么'defer recover()'不捕捉死机?有鉴于此:我们给这些行编号:
上述代码的执行过程如下:
L2:评估
o()
的参数,f()
被调用,x
递增到1
(稍后将打印)。o()
尚未被调用。L3:延迟函数尚未被调用,现在跳过其整个函数体。
L7:
f()
尚未被调用,x
仍然是1
。未调用L8:
recover()
。L9:调用
f()
,将x
递增为2
,并返回它,因此2
被传递给panic()
。我们处于一个恐慌状态,所以延迟的函数现在执行(以LIFO顺序)。
调用L8:
recover()
,但不停止恐慌状态。L7:现在调用
f()
,将x
递增到3
。L3:现在执行这个匿名函数。
L4:
recover()
返回2
(传递给panic()
的值),这将在以后打印,但还没有,因为对o()
的调用被延迟。L5:调用
f()
,将x
递增为4
,立即打印。L4:现在执行延迟函数
o()
,打印上述值2
。L2:现在执行延迟函数
o()
,打印先前计算的值1
。程序结束。