Получить доступ

Как работает defer и в каком порядке выполняются отложенные вызовы?

JuniorОсновы языка
Ещё спрашивают так:
  • Когда вычисляются аргументы defer?
  • Можно ли изменить возвращаемое значение в defer?
Коротко

defer откладывает вызов до выхода из функции — при обычном return и при panic. Отложенные вызовы выполняются в порядке LIFO (последний — первым). Аргументы вычисляются сразу в момент defer, а не при выполнении. Через именованные результаты defer может изменить возвращаемое значение.

  • Типичное применение: f.Close(), mu.Unlock(), recover
  • defer в цикле копит вызовы до конца функции — ресурсы держатся долго
  • Ошибку Close при записи файла не стоит игнорировать

А ещё Стоимость defer в Go 1.14+ почти нулевая

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Вычисление аргументов. defer fmt.Println(x) запоминает значение x в момент выполнения строки defer. Если нужна актуальная переменная — замыкание: defer func() { fmt.Println(x) }().

defer в цикле. Открывая тысячу файлов в цикле с defer f.Close(), все они закроются только в конце функции — исчерпание дескрипторов. Решение — вынести тело цикла в отдельную функцию.

Возвращаемое значение. return x сначала присваивает результат, затем выполняет отложенные вызовы. Если результат именованный, defer может его прочитать и изменить — так обрабатывают ошибку закрытия и превращают panic в error.

Пример

func read(path string) (err error) {
    f, err := os.Open(path)
    if err != nil { return err }
    defer func() {
        if cerr := f.Close(); cerr != nil && err == nil {
            err = cerr                 // меняем именованный результат
        }
    }()
    ...
}

for i := 0; i < 3; i++ {
    defer fmt.Println(i)   // напечатает 2, 1, 0
}

Что хотят услышать

  • Когда выполняется и порядок LIFO.
  • Момент вычисления аргументов.
  • Ловушка defer в цикле.

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем