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