AnyCompiler

defer, panic, and recover

defer schedules a function call to run right before the surrounding function returns, regardless of how it returns. It's most often used for cleanup — closing a file, unlocking a mutex — written right next to the code that opened it.

package main

import "fmt"

func main() {
	fmt.Println("start")
	defer fmt.Println("cleanup")
	fmt.Println("end")
}
Output
start
end
cleanup

panic and recover

panic immediately stops normal execution and starts unwinding the call stack — Go's closest equivalent to throwing an exception, reserved for truly exceptional situations, not everyday error handling. recover, called inside a deferred function, stops that unwinding and lets the program continue, which is how safeDivide below turns a runtime panic (dividing by zero) into an ordinary returned value.

package main

import "fmt"

func safeDivide(a, b int) (result int) {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("recovered from:", r)
			result = 0
		}
	}()
	return a / b
}

func main() {
	fmt.Println(safeDivide(10, 2))
	fmt.Println(safeDivide(10, 0))
}
Output
5
recovered from: runtime error: integer divide by zero
0

Next: closures — functions that capture variables from their surrounding scope.

Practice exercise

Use defer to print "goodbye" after printing "hello" (defer should make "goodbye" print last, even though it appears first in the code).