Defer, panic, recover: механизм обработки ошибок
Вопрос
Объясните работу defer, panic и recover. Как они взаимодействуют? В каких случаях следует использовать panic/recover?
Ответ
defer: - Выполняется в обратном порядке (LIFO) при выходе из функции - Выполняется даже при panic - Аргументы вычисляются сразу, но вызов откладывается panic: - Останавливает нормальное выполнение - Раскручивает стек, выполняя defer'ы - Должен использоваться только для критических ошибок recover: - Может перехватить panic только внутри defer - Возвращает значение, переданное в panic
func riskyFunction() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Перехвачен panic: %v
", r)
}
}()
defer fmt.Println("Этот defer выполнится")
panic("Что-то пошло не так!")
fmt.Println("Эта строка не выполнится")
}
func main() {
riskyFunction()
fmt.Println("Программа продолжает работу")
}
func riskyFunction() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Перехвачен panic: %v
", r)
}
}()
defer fmt.Println("Этот defer выполнится")
panic("Что-то пошло не так!")
fmt.Println("Эта строка не выполнится")
}
func main() {
riskyFunction()
fmt.Println("Программа продолжает работу")
}
Дополнительные вопросы
Что происходит с defer при выходе из горутины? Как panic в одной горутине влияет на другие?