Как работают panic, defer и recover
Вопрос
Расскажите, как устроены defer, panic и recover, где и зачем вы используете recover, и что нельзя перехватить.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
defer кладёт вызов в список горутины, аргументы вычисляются сразу; выполняются LIFO при выходе
С Go 1.14 open-coded defer: почти бесплатный для простых случаев
panic разматывает стек текущей горутины, выполняя defer
recover работает только напрямую в отложенной функции той же горутины
Не перехватываются fatal error: concurrent map writes, нехватка памяти, deadlock
Использование: middleware сервера, обёртка воркеров, превращение паники в ошибку на границе библиотеки
Что могут спросить следом
- Что будет, если паника случится внутри defer во время другой паники?
- Почему не стоит использовать panic как исключение для обычных ошибок?
Разбор
defer регистрирует вызов, аргументы которого вычислены сразу, а выполняется он при выходе из функции в обратном порядке. С Go 1.14 простые defer без циклов компилятор встраивает прямо в код выхода (open-coded defer), поэтому их стоимость почти нулевая, и бояться defer в горячем коде больше не нужно. panic останавливает обычное выполнение и разматывает стек текущей горутины, выполняя отложенные функции. Если одна из них вызвала recover напрямую, паника останавливается, и функция с этим defer возвращается нормально, с теми именованными результатами, которые выставил defer. Если никто не перехватил, печатается паника со стеком и процесс завершается с кодом 2. Новая паника в defer во время паники заменяет текущую, а в выводе видны обе. recover использую на границах: middleware HTTP, обёртка горутин-воркеров, публичный API библиотеки, где паника внутри превращается в error. Нельзя перехватить fatal error рантайма: конкурентная запись в мапу, исчерпание памяти, deadlock всех горутин, переполнение стека. Для обычных ошибок panic не использую: это дорого, ломает явный поток управления и легко забыть recover в новой горутине.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.