Что делает defer и в каком порядке выполняются несколько отложенных вызовов?
Прочитайте фрагмент ниже. Три оператора defer регистрируются до завершения тела функции.
Определите порядок, в котором печатаются строки, и объясните, что делает defer и в каком порядке выполняются несколько отложенных вызовов.
func main() {
defer fmt.Println("one")
defer fmt.Println("two")
defer fmt.Println("three")
fmt.Println("body")
}
Определите вывод.
defer планирует вызов на момент возврата из охватывающей функции. Несколько отложенных вызовов выполняются в порядке LIFO — зарегистрированный последним выполняется первым — поэтому печатаются в обратном порядке.
- ✗Ожидать, что отложенные вызовы выполнятся в порядке регистрации (FIFO), а не LIFO
- ✗Думать, что
deferвыполняет вызов сразу, а не при возврате из функции - ✗Считать, что отложенный вызов пропускается при panic в функции
- →Выполнится ли отложенный вызов, если в функции произойдёт panic?
- →Где хранятся отложенные вызовы для одной goroutine?
Что выведет код?
package main
import "fmt"
func main() {
defer fmt.Println("один")
defer fmt.Println("два")
defer fmt.Println("три")
fmt.Println("тело")
}
Вывод:
тело
три
два
один
Сначала выполняется тело main. При возврате из функции отложенные вызовы выполняются в порядке LIFO: последний зарегистрированный ("три") — первым, первый зарегистрированный ("один") — последним. Отложенные вызовы помещаются в стек, привязанный к текущему вызову функции, и срабатывают при выходе из неё, в том числе при panic.