Go: defer и recover, объявленный после panic

Данный код скомпилируется, но при запуске приведёт к панике, и не выведет ожидаемого результата из-за порядка вызова defer и panic.

Короткий ответ

Что ответить на собеседовании

Данный код скомпилируется, но при запуске приведёт к панике, и не выведет ожидаемого результата из-за порядка вызова defer и panic.

Подробный разбор

Ответ с пояснениями

Условие

// Вопрос 2. Что выведет на экран

package main

import "fmt"

func main() { { defer fmt.Println(1) } defer fmt.Println(2)

panic("aaaa")
defer func(){
    if r := recover(); r != nil{
        fmt.Println("Паника обработана", r)
    }
}()

}

Ответ

Данный код скомпилируется, но при запуске приведёт к панике, и не выведет ожидаемого результата из-за порядка вызова defer и panic.

Разбор:

  • Внутри блока { defer fmt.Println(1) } отложен вывод 1.
  • Затем отложен вывод 2.
  • Затем вызывается panic("aaaa").
  • После panic вызывается последний defer с функцией, которая пытается сделать recover.

Однако, в Go defer-выражения выполняются в обратном порядке их объявления при выходе из функции, включая выход из-за panic.

Порядок выполнения defer при panic:

  1. Выполняется последний defer — функция с recover.
  2. Если recover срабатывает, паника прекращается, и программа продолжает выполнение.
  3. Затем выполняются остальные defer — fmt.Println(2) и fmt.Println(1).

Но в данном коде defer с recover объявлен после panic, то есть он не будет вызван, так как panic прерывает выполнение сразу.

На самом деле, код не скомпилируется, потому что после panic идут defer, что недопустимо — panic прерывает выполнение, и последующий код не выполняется.

Если бы defer с recover был объявлен до panic, то вывод был бы:

Паника обработана aaaa
2
1

Итог: в текущем виде код вызовет panic и завершится с ошибкой, не выведя ничего, так как defer с recover объявлен после panic и не сработает.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее