我正在尝试使用 Go 并且看到一些带有延迟函数的意外行为。考虑以下将全局变量增加给定数量的程序。
package main
import "fmt"
var z = 1
func main() {
defer increaseZ(10)
defer fmt.Println("z =", increaseZ(20), "Deferred Value 1")
defer fmt.Println("z =", increaseZ(30), "Deferred Value 2")
fmt.Println("z =", z, "Main Value")
}
func increaseZ(y int) int {
z += y
println("z =", z, "Inside Increase Function")
return z
}
当在 go playground 中运行时,输出:
z = 21 Inside Increase Function
z = 51 Inside Increase Function
z = 61 Inside Increase Function
z = 51 Main Value
z = 51 Deferred Value 2
z = 21 Deferred Value 1
如果我切换延迟函数的顺序,它还有另一个效果:
defer fmt.Println("z =", increaseZ(20), "Deferred Value 1")
defer fmt.Println("z =", increaseZ(30), "Deferred Value 2")
defer increaseZ(10)
输出:
z = 21 Inside Increase Function
z = 51 Inside Increase Function
z = 51 Main Value
z = 61 Inside Increase Function
z = 51 Deferred Value 2
z = 21 Deferred Value 1
Go 文档指出:
延迟调用的参数会立即计算,但直到周围的函数返回时才会执行函数调用。
因此,正在评估的参数可以解释为什么返回的 Main Value 是 51 而不是 61,因为 fmt.Println 语句将increaseZ作为参数,但defer increaseZ(10)在 main 函数返回之前不会被调用。
但是,这并不能解释为什么在第一个示例中increaseZ(10)在 main 完成之前输出,而在第二个示例中在 main 完成之后输出。
如果有人能帮助我了解这里发生的事情,我将不胜感激,因为这看起来像是难以诊断错误的沃土。
BIG阳
红糖糍粑
相关分类