Как работает defer и в каком порядке выполняются отложенные вызовы?
- Когда вычисляются аргументы defer?
- Можно ли изменить возвращаемое значение в defer?
defer откладывает вызов до выхода из функции — при обычном return и при panic. Отложенные вызовы выполняются в порядке LIFO (последний — первым). Аргументы вычисляются сразу в момент defer, а не при выполнении. Через именованные результаты defer может изменить возвращаемое значение.
- Типичное применение: f.Close(), mu.Unlock(), recover
- defer в цикле копит вызовы до конца функции — ресурсы держатся долго
- Ошибку Close при записи файла не стоит игнорировать
А ещё Стоимость defer в Go 1.14+ почти нулевая
Подробно
Вычисление аргументов. 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 в цикле.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Отложенные вызовы выполняются в порядке объявления
- ✓LIFO при выходе из функции, даже при panic; аргументы вычисляются сразу
- ✗Аргументы defer вычисляются в момент самого вызова
- ✗defer не выполняется при panic
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.