How to use a defer statement

yourbasic.org/golang

A deferred method call is executed just before leaving the surrounding function.

func main() {
    defer fmt.Println("World")
    fmt.Println("Hello")
}
Hello
World

Deferred calls are executed even when the function panics.

func main() {
    defer fmt.Println("World")
    panic("Stop")
    fmt.Println("Hello")
}
World
panic: Stop

goroutine 1 [running]:
main.main()
    ../main.go:3 +0xa0

Deferred function calls are executed in last-in-first-out order, and a deferred function’s arguments are evaluated when the defer statement executes.

func main() {
    fmt.Println("Hello")
    for i := 1; i <= 3; i++ {
        defer fmt.Println(i)
    }
    fmt.Println("World")
}
Hello
World
3
2
1

Deferred functions may access and modify the surrounding function’s named return parameters.

func foo() (result string) {
    defer func() {
        result = "Change World" // change value at the very last moment
    }()
    return "Hello World"
}

The foo function returns “Change World”.

Clean-up

Defer is commonly used to perform clean-up actions, such as closing a file or unlocking a mutex. In this example 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 Recover from a panic article demonstrates how to use a defer statement to recover from a panic.