Go: Defer statement
A deferred method call is executed just before leaving the surrounding function.
Example: Executed before normal return:
func main() {
defer fmt.Println("World")
fmt.Println("Hello")
}
Output:
Hello World
Deferred calls are executed even when the function panics.
Example: Executed during panic:
func main() {
defer fmt.Println("World")
panic("Eeek")
fmt.Println("Hello")
}
Output:
World panic: Eeek <stack trace...>
A deferred function's arguments are evaluated when the defer statement executes.
Deferred function calls are executed in last-in-first-out order.
Example: Three deferred calls:
func main() {
fmt.Println("start")
for i := 1; i <= 3; i++ {
defer fmt.Println(i)
}
fmt.Println("end")
}
Output:
start end 3 2 1
Deferred functions may access and modify the surrounding function's named return parameters:
Example: Change return value at the very last moment:
func Foo() (result int) {
defer func() {
result = 7
}()
return 0
}
Foo()
returns 7.
Clean-up
Defer is commonly used to perform clean-up actions, such as closing a file or unlocking a mutex.
Example: Here defer statements are used to ensure that all files are closed before leaving the CopyFile
function, whichever way that happens.
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
defer src.Close()
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close()
return io.Copy(dst, src)
}
Recover from panic
The article Recover from a panic demonstrates how to use a defer statement when recovering from a panic.