defer

defer откладывает выполнение функции до возврата из текущей функции:

func readFile(name string) {
    f, _ := os.Open(name)
    defer f.Close()   // выполнится при выходе из readFile

    // работа с файлом
}

Ресурс открыт и сразу «подстрахован» — независимо от того, сколько путей выхода из функции.

Несколько defer выполняются в порядке LIFO — последний зарегистрированный вызывается первым:

func main() {
    defer fmt.Println("третий")
    defer fmt.Println("второй")
    defer fmt.Println("первый")
}
// первый
// второй
// третий

Аргументы отложенной функции вычисляются в момент регистрации defer, а не при вызове:

x := 5
defer fmt.Println(x)   // напечатает 5, даже если x изменится
x = 10

defer — стандартный паттерн для освобождения ресурсов: закрыть файл, разблокировать мьютекс, завершить транзакцию. Надёжнее, чем вручную следить за всеми путями возврата.


ЗаданиеСложность
1Упражнение 1easy
2Упражнение 2easy
3Упражнение 3medium
4Упражнение 4medium