Ответ
recover
— это встроенная функция в Go, предназначенная для перехвата паники (panic
) и восстановления нормального выполнения горутины.
Ключевое правило: recover
работает только внутри функции, отложенной с помощью defer
. Если recover
вызывается вне defer
или в горутине, где не было паники, она вернет nil
и не будет иметь никакого эффекта.
Пример работы:
package main
import "fmt"
func main() {
// defer гарантирует, что эта функция выполнится перед выходом из main,
// даже если произойдет паника.
defer func() {
// recover() перехватывает значение, переданное в panic()
if r := recover(); r != nil {
fmt.Println("Восстановлено после паники:", r)
}
}()
fmt.Println("Вызываем функцию, которая паникует.")
causePanic()
// Эта строка никогда не выполнится, так как управление перейдет к defer.
fmt.Println("Функция main завершается штатно.")
}
func causePanic() {
fmt.Println("Сейчас будет паника!")
panic("произошла критическая ошибка")
}
// Вывод:
// Вызываем функцию, которая паникует.
// Сейчас будет паника!
// Восстановлено после паники: произошла критическая ошибка
Когда следует использовать recover
?
Использование panic
/recover
для обычной обработки ошибок считается плохой практикой. Для этого в Go существует механизм возврата error
.
Основные сценарии для recover
:
Предотвращение падения всего приложения: В серверах (например, HTTP-сервер)
recover
используется вdefer
на верхнем уровне горутины, обрабатывающей запрос. Это позволяет изолировать панику: одна неудачная обработка запроса не приведет к падению всего сервера.В библиотеках: Чтобы паника внутри библиотеки не "протекла" наружу и не обрушила приложение, которое её использует. В этом случае панику можно перехватить и вернуть как обычное значение
error
.