Why is Go’s “defer” scoped to function, not lexical enclosure?

  1. Is my understanding correct?

Yes.

  1. Is there a way to scope it to the block […]?

There is no way to change how defer works. Depending on the problem you are trying to solve, perhaps splitting your function (first example below) or defining anonymous functions (second example) would help. The latter just for reference and probably best avoided because of how it makes the code less readable.

More info on defer at Go Spec.

Split

package main

import (
    "fmt"
)

func main() {
    fmt.Println("main")
    defer fmt.Println("defer from main")
    f()
}

func f() {
    fmt.Println("f")
    defer fmt.Println("defer from f")
}
main
f
defer from f
defer from main

→ playground

Anonymous functions

package main

import (
    "fmt"
)

func main() {
    fmt.Println("outer func")
    defer fmt.Println("defer from outer func")
    func() {
        fmt.Println("first inner func")
        defer fmt.Println("defer from first inner func")
    }()
    func() {
        fmt.Println("second inner func")
        defer fmt.Println("defer from second inner func")
    }()
}
outer func
first inner func
defer from first inner func
second inner func
defer from second inner func
defer from outer func

→ playground

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)