在计算defer语句时会计算延迟函数的参数。
这让我很困惑。
问题:“已评估”是否表示该值已知?我只是不明白为什么两个例子打印不同。这让我很困惑。
我有以下两个例子:
//It prints 0.
func deferA() {
i := 0
defer fmt.Println(i)
i++
return
}
//It prints 1.
func deferB() {
i := 0
defer func() {
fmt.Println(i)
}()
i++
return
}
答案 0 :(得分:3)
defer
接受一个函数,因此fmt.Println(i)
是一个函数,当评估defer语句时,它的参数i
被评估为0
。
defer func() { fmt.Println(i) }
,func() { fmt.Println(i) }
不带参数,它是一个闭包,所以i
不会被评估,而是由闭包关闭。
答案 1 :(得分:1)
评估函数参数,但不评估函数本身。
在第一种情况下,对参数I
进行求值,并准备将值0
传递给函数。这就是延迟函数打印0
的原因。
在第二种情况下,没有要评估的论据。但是函数从外部函数中包含值。因此它可以直接访问其实际价值。
您可以在不关闭的情况下获得相同的结果。传递变量i
的地址。逻辑是相同的:地址被计算并传递给函数。具有此地址功能可以访问实际变量值。尝试检查它是如何工作的。