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