Go - Inconsistent Evaluation of Deferred Functions -
i experimenting go , seeing unexpected behaviour deferred functions. consider following program increments global variable given amount.
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 }
when run in go playground, outputs:
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
if switch order of deferred functions, has effect:
defer fmt.println("z =", increasez(20), "deferred value 1") defer fmt.println("z =", increasez(30), "deferred value 2") defer increasez(10)
outputs:
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
the go documentation states:
the deferred call's arguments evaluated immediately, function call not executed until surrounding function returns.
so arguments being evaluated, may explain why main value returned 51 , not 61, since fmt.println statements taking increasez
argument, defer increasez(10)
not called until after main function returns.
however, not explain why in first example increasez(10)
outputting before main has completed, , after main has completed in second example.
i grateful if me understand happening here, since looks fertile ground difficult diagnose bugs further down line.
you being inconsistent in print destination.
stdout: fmt.println stderr: println
write same print destination.
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 }
output:
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
or,
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 }
output:
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
Comments
Post a Comment