Ответ
Ключевое слово defer
в Go используется для отложенного выполнения вызова функции до тех пор, пока содержащая её функция не завершит свое выполнение. Основное предназначение defer
— это управление ресурсами, такими как закрытие файлов, разблокировка мьютексов или закрытие сетевых соединений.
Пример с закрытием файла:
func processFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
// file.Close() будет вызван непосредственно перед выходом из processFile,
// независимо от того, как функция завершится (через return или панику).
defer file.Close()
// ... код для работы с файлом ...
return nil
}
Ключевые особенности defer
:
-
Порядок выполнения LIFO (Last-In, First-Out): Если в функции есть несколько
defer
вызовов, они будут выполнены в порядке, обратном их объявлению. Последний объявленныйdefer
выполнится первым.func lifoExample() { defer fmt.Println("третий") defer fmt.Println("второй") defer fmt.Println("первый") } // Вывод будет: // первый // второй // третий
-
Вычисление аргументов в момент вызова: Аргументы отложенной функции вычисляются в тот момент, когда компилятор встречает оператор
defer
, а не когда функция фактически выполняется. -
Гарантированное выполнение: Отложенный вызов гарантированно выполнится, даже если в функции произойдет
panic
. Это делаетdefer
идеальным инструментом для очистки ресурсов. -
Взаимодействие с именованными результатами:
defer
может читать и изменять именованные возвращаемые значения функции. Это полезно для обработки ошибок или модификации результата перед возвратом.func getNumber() (result int) { defer func() { // Этот код выполнится после 'return 10', // но до фактического возврата значения из функции. result *= 2 }() return 10 } // getNumber() вернет 20