Ответ
Отложенные функции в Go, объявленные с помощью ключевого слова defer
, выполняются в обратном порядке их объявления — по принципу LIFO (Last-In, First-Out). Последняя объявленная defer
функция выполнится первой.
Выполнение всех отложенных функций происходит в момент, когда окружающая их функция собирается завершиться: либо через return
, либо в конце блока кода, либо из-за паники.
Пример порядка выполнения:
package main
import "fmt"
func main() {
fmt.Println("Начало main")
defer fmt.Println("Вызов 1 (выполнится последним)")
defer fmt.Println("Вызов 2")
defer fmt.Println("Вызов 3 (выполнится первым)")
fmt.Println("Конец main")
}
Вывод:
Начало main
Конец main
Вызов 3 (выполнится первым)
Вызов 2
Вызов 1 (выполнится последним)
Ключевые особенности defer
:
-
Немедленное вычисление аргументов: Аргументы для отложенной функции вычисляются в момент объявления
defer
, а не в момент её выполнения.func printArgument() { i := 0 defer fmt.Println("Значение i:", i) // i = 0 i++ // Вывод будет "Значение i: 0", так как i было вычислено в строке с defer }
-
Гарантированное выполнение:
defer
полезен для освобождения ресурсов (например, закрытие файловfile.Close()
или разблокировка мьютексовmu.Unlock()
), так как он будет выполнен даже если в функции произойдет паника.