Ответ
Основная задача recover() — перехватить панику, чтобы предотвратить аварийное завершение программы и выполнить код для graceful shutdown или обработки ошибки.
recover() эффективно работает только при вызове внутри отложенной функции (defer), потому что:
- Когда возникает паника, нормальное выполнение функции немедленно прекращается.
- Исполнение переходит к выполнению
deferфункций, которые были отложены в этой горутине. - Только на этом этапе
recover()может "поймать" панику. Если вызватьrecover()внеdefer, он просто вернетnil, так как в момент его вызова паники еще (или уже) нет.
Пример корректного использования:
func safeFunc() {
defer func() {
// recover() перехватывает значение, переданное в panic()
if r := recover(); r != nil {
fmt.Println("Перехвачена паника:", r)
}
}()
fmt.Println("Начало выполнения safeFunc")
// Симуляция критической ошибки
panic("что-то пошло не так")
// Этот код никогда не выполнится
fmt.Println("Завершение выполнения safeFunc")
}Ключевые моменты:
- Место вызова:
recover()должен быть вызван непосредственно изdeferфункции. Вызов из функции, которую вызываетdefer, не сработает. - Возвращаемое значение: Возвращает значение, переданное в
panic(), илиnil, если паники не было. - Продолжение выполнения: После успешного
recover()паника прекращается, и выполнение продолжается со следующего оператора после вызова функции, в которой произошла паника. Сама запаниковавшая функция не возобновляет свою работу.