我正在尝试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
}
当run in the 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文档指出:
The deferred call's arguments are evaluated immediately, but the
function call is not executed until the surrounding function returns.
因此,正在评估的参数可以解释为什么返回的Main Value是51而不是61,因为fmt.Println语句将increaseZ 作为参数,但是直到主函数返回后才调用defer increaseZ(10) 。
但是,这并不能解释为什么在第一个示例中在main完成之前和main完成之后才输出increaseZ(10) 。
如果有人能帮助我了解这里发生的事情,我将不胜感激,因为这看起来像肥沃的土地,难以进一步诊断错误。
Best Answer-推荐答案 strong>
您的打印目的地不一致。
stdout: fmt.Println
stderr: println
写入相同的打印目的地。
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
fmt.Println("z =", z, "Inside Increase Function")
return z
}
输出:
z = 21 Inside Increase Function
z = 51 Inside Increase Function
z = 51 Main Value
z = 51 Deferred Value 2
z = 21 Deferred Value 1
z = 61 Inside Increase Function
或者,
package main
import (
"fmt"
"os"
)
var z = 1
func main() {
defer increaseZ(10)
defer fmt.Fprintln(os.Stderr, "z =", increaseZ(20), "Deferred Value 1")
defer fmt.Fprintln(os.Stderr, "z =", increaseZ(30), "Deferred Value 2")
fmt.Fprintln(os.Stderr, "z =", z, "Main Value")
}
func increaseZ(y int) int {
z += y
println("z =", z, "Inside Increase Function")
return z
}
输出:
z = 21 Inside Increase Function
z = 51 Inside Increase Function
z = 51 Main Value
z = 51 Deferred Value 2
z = 21 Deferred Value 1
z = 61 Inside Increase Function
关于go - Go-延迟函数的不一致评估,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/29316958/
|