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