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