gopherdata/gophernotes

defer outside a function

kofj opened this issue · 1 comments

kofj commented
import (
    "fmt"
    "time"
)

func calc(index string, a, b int) int {
     time.Sleep(1e9)
    ret := a + b
    fmt.Println(time.Now().Unix(),"\t",index,"\t", a, "\t", b, "\t", ret)
    return ret
}

// func main() {
    a := 1
    b := 2
//     defer calc("1", a, 3)
    defer calc("1", a, calc("10", a, b))

    a = 0
//     defer calc("2", a, 2)
    defer calc("2", a, calc("20", a, b))
    b = 1
// }

// log.Println("\n\n")

WANT

1572422679 	 10 	 1 	 2 	 3
1572422680 	 20 	 0 	 2 	 2
1572422681 	 2 	 0 	 2 	 2
1572422682 	 1 	 1 	 3 	 4

But, got:

1572423309 	 10 	 1 	 2 	 3
1572423310 	 1 	 1 	 3 	 4
1572423311 	 20 	 0 	 2 	 2
1572423312 	 2 	 0 	 2 	 2

Using defer outside a function is an extension - compiled Go does not allow it.
Gophernotes instead does, and implements it as follows:

  1. defer at top level, i.e. outside any block, is executed immediately - not at the end of the cell
  2. defer inside a block is executed when the outermost block completes

So to obtain what you expect, just wrap the code in a block:

import (
    "fmt"
    "time"
)

func calc(index string, a, b int) int {
     time.Sleep(1e9)
    ret := a + b
    fmt.Println(time.Now().Unix(),"\t",index,"\t", a, "\t", b, "\t", ret)
    return ret
}

{
    a := 1
    b := 2
    defer calc("1", a, calc("10", a, b))

    a = 0
    defer calc("2", a, calc("20", a, b))
    b = 1
}