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")
}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))
}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).