Ответ
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, предоставляя вызывающему коду решать, как на них реагировать.
Ответ 18+ 🔞
Ну, слушай, смотри, я тебе сейчас про panic в Go расскажу, но так, чтобы ты реально понял, а не просто термины гонял. Это, блядь, не просто функция — это такой крик души программы, когда она понимает, что всё, пиздец, дальше жить нельзя.
Чем это не error?
error: Это как когда ты в магазин идёшь, а там картошки нет. Ну, бывает, пошёл в другой. Ошибка, но ожидаемая, с ней можно жить. Функция тебе её возвращает, а ты уже думаешь, что делать.panic: А это когда ты уже на кухне, картошку чистишь, а ножом по пальцу — хрясь! И палец, сука, чуть не отвалился. Вот это пиздец, это уже не до ужина. Дальше готовить опасно, надо всё бросать и скорую вызывать. Это ошибка, после которой нормально работать уже не получится.
Как эта паника работает, эта сука:
- Всё, стоп-кран! Текущая функция сразу встаёт как вкопанная.
- Начинается "раскрутка стека" — это как когда ты падаешь с лестницы и по пути хватаешься за всё, что видишь (
defer-функции как раз успеют отработать). - Если никто не успеет тебя поймать (
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) // Бдыщь!
}
Так когда же эту панику вызывать, ебать?
- В
main-функции: Когда программа только стартует, а у неё уже всё хуёво — конфиг не прочитался, порт занят. Ну нахуй так жить, лучше сразу умереть. - При ошибках программиста: Когда в логике программы случилась такая дичь, что проще всё убить, чем пытаться исправить на ходу. Например, бесконечная рекурсия или обращение к
nil. Это сигнал: "Чувак, тут код кривой, иди фикси".
Главное правило, чтобы не быть мудаком: Не используй panic в библиотеках для обычных бытовых ошибок! Ты же не знаешь, какую логику восстановления захочет написать тот, кто твой код использует. Возвращай нормальный error, пусть сам решает — завершаться ему или ещё побороться. Паника — это последнее средство, когда терпения ебать ноль и доверия к состоянию программы — тоже.