gopherdata / gophernotes

The Go kernel for Jupyter notebooks and nteract.
MIT License
3.84k stars 265 forks source link

defer outside a function #186

Closed kofj closed 4 years ago

kofj commented 4 years ago
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
cosmos72 commented 4 years ago

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
}