AnyCompiler

defer, panic, y recover

defer programa una llamada a función para que se ejecute justo antes de que retorne la función que la contiene, sin importar cómo retorne. Se usa con más frecuencia para la limpieza — cerrar un archivo, desbloquear un mutex — escrito justo al lado del código que lo abrió.

package main

import "fmt"

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

panic y recover

panic detiene inmediatamente la ejecución normal y empieza a desenrollar la pila de llamadas — el equivalente más cercano de Go a lanzar una excepción, reservado para situaciones genuinamente excepcionales, no para el manejo de errores cotidiano. recover, llamado dentro de una función diferida, detiene ese desenrollado y deja que el programa continúe, que es cómo safeDivide de abajo convierte un panic en tiempo de ejecución (dividir por cero) en un valor de retorno ordinario.

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

Siguiente: closures — funciones que capturan variables de su ámbito circundante.

Practice exercise

Usa defer para imprimir "goodbye" después de imprimir "hello" (defer debe hacer que "goodbye" se imprima al final, aunque aparezca primero en el código).