# defer утверждения (defer statements)

**Утверждение "defer"** вызывает функцию, выполнение которой откладывается до момента, когда окружающая функция возвращается, потому что выполнила утверждение return, либо когда достигла конца своего тела функции, либо когда соответствующая go-процедура (goroutine) запаниковала.

```
DeferStmt = "defer" Expression .
```

Выражение должно быть вызовом функции или метода; оно не может быть заключено в скобки. Вызовы встроенных функций ограничены как для утверждений выражений.

Каждый раз, когда выполняется утверждение "defer", значение функции и параметры для вызова оцениваются как обычно и сохраняются заново, но фактическая функция не вызывается. Вместо этого отложенные функции **вызываются непосредственно перед возвратом окружающей функции** в обратном порядке. То есть, если окружающая функция возвращается через явное return утверждение, отложенные функции выполняются после того, как этот return утверждение установит какие-либо параметры результата, но до того, как функция вернется к своему вызывающему. Если значение отложенной функции оценивается как nil, выполнение вызывает панику при вызове функции, а не при выполнении утверждения "defer".

Например, если отложенная функция является литералом функции, а окружающая функция имеет именованные параметры результата, которые находятся в области видимости внутри литерала, отложенная функция может получить доступ к параметрам результата и изменить их, прежде чем они будут возвращены. Если отложенная функция имеет какие-либо возвращаемые значения, они отбрасываются после завершения функции.

```
lock(l)
// разблокировка происходит до возврата окружающей функции
defer unlock(l)  

// печатает 3 2 1 0 до возвращения окружающей функции
for i := 0; i <= 3; i++ {
    defer fmt.Print(i)
}

// f возвращает 42
func f() (result int) {
    defer func() {
        // результат доступен после того, 
        // как он был установлен в 6 оператором return
        result *= 7
    }()
    return 6
}
```
