Defer

The defer keyword is a fairly unique feature of Go. It allows a function to be executed automatically just before its enclosing function returns. The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.

Deferred functions are typically used to clean up resources that are no longer being used β€” often to close database connections, file handlers, and the like.

circle-info

The deferred call's arguments are evaluated at the point the defer statement executes, but the actual function call runs only when the surrounding function is about to return.

Example

example.go
func GetUsername(dstName, srcName string) (username string, err error) {
	// Open a connection to a database
	conn, _ := db.Open(srcName)

	// Close the connection *anywhere* the GetUsername function returns
	defer conn.Close()

	username, err = db.FetchUser()
	if err != nil {
		// The defer statement is auto-executed if we return here
		return "", err
	}

	// The defer statement is auto-executed if we return here
	return username, nil
}

In the above example, the conn.Close() function is not called at the defer statement itself:

It's called when the surrounding function returns:

Depending on whether the FetchUser function errored.

1

Define and schedule the deferred call

Place the defer statement after resource acquisition so the cleanup is guaranteed:

Example: defer conn.Close()

2

Return from the surrounding function (at any return point)

When the function executes a return (or reaches its end), the deferred calls are executed in LIFO order.

3

Deferred function executes just before the function fully returns

The actual cleanup happens here β€” after return arguments are set but before control returns to the caller.

Defer is a great way to make sure that something happens before a function exits, even if there are multiple return statements.