Why add "()" after closure body in Golang?

It's not that () must be added after (only) a closure in defer. The language specs for the defer statement mandate that its 'Expression' always must be a function call.

And why is it so? It's the same as with any other function, in 'defer' or not:

Consider:

func f() int { return 42 }

and

a := f

vs

b := f()

The first expression RHS is a function value. In the second version the RHS is the value returned by the function - i.e. a function call.

So is the semantics of:

defer f

vs

defer f()

except that the first version doesn't make sense in the context of 'defer', and so the specifications mention that it must be the second form (only).

It's IMHO also easier to learn because of the orthogonality with the above discussed function call outside of the 'defer' statement.

Also note that a function call is not only fn-expr followed by (), but an expression list is generally inside the parenthesis (including an empty list). There's a big difference between:

for i := range whatever {
        defer func() { fmt. Println(i) }()
}

and

for i := range whatever {
        defer func(n int) { fmt. Println(n) }(i)
}

The first version prints the value of 'i' in the moment when the closure executes, the second prints the value of 'i' in the moment when the defer statement was executed.


If you don't want to read long answers:

str := "Alice"
go func(name string) {
    fmt.Println("Your name is", name)
}(str)

Is same as:

str := "Alice"
f := func(name string) {
    fmt.Println("Your name is", name)
}
go f(str)