AnyCompiler

defer, panic, e recover

defer agenda uma chamada de function para rodar bem antes da function ao redor retornar, não importa como ela retorne. É usado com mais frequência para limpeza — fechar um arquivo, destravar um mutex — escrito bem ao lado do código que o abriu.

package main

import "fmt"

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

panic e recover

panic para imediatamente a execução normal e começa a desenrolar a call stack — o equivalente mais próximo do Go a lançar uma exception, reservado para situações verdadeiramente excepcionais, não para tratamento de erros do dia a dia. recover, chamado dentro de uma function diferida, para esse desenrolamento e deixa o programa continuar, e é assim que safeDivide abaixo transforma um panic em tempo de execução (dividir por zero) em um valor de retorno comum.

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

A seguir: closures — functions que capturam variáveis do escopo ao redor delas.

Practice exercise

Use defer para imprimir "goodbye" depois de imprimir "hello" (defer deve fazer "goodbye" imprimir por último, mesmo aparecendo primeiro no código).