I was surprised to find that these two programs produce the same output:
Program A
package main
import "fmt"
func main() {
defer fmt.Println(1)
defer fmt.Println(2)
}
Program B
package main
import "fmt"
func main() {
{
defer fmt.Println(1)
}
defer fmt.Println(2)
}
In other words, the "defer" statement appears to disregard lexical closures [edit: Thanks to @twotwotwo for correcting my terminology, I meant to say "block" not "lexical closure"] and is strictly scoped to the function. I wondered:
I can imagine doing several units of work in sequence, each requiring its own resource to be closed before proceeding... would be nice not to have to break them into separate functions solely for that purpose.
In Golang, the defer keyword is used to delay the execution of a function or a statement until the nearby function returns. In simple words, defer will move the execution of the statement to the very end inside a function.
A deferred function call is a function call which follows a defer keyword. The defer keyword and the deferred function call together form a defer statement. Like goroutine function calls, all the results of the function call (if the called function has return results) must be discarded in the function call statement.
Defer is more like a finally block in languages like Java or Python: something that has to be executed after attempting to run some code – whether or not it succeeds. This is useful in cases where you have to run some clean-up operation after some code executes. For example: Closing a file after opening it.
defer won't work after panic because the control never reached the statement, hence it was never registered. This is like printing something after a return statement in a function, it's basically an unreachable code.
- Is my understanding correct?
Yes.
- 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 (example) or defining anonymous functions (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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With