пятница, 21 июня 2019 г.

Спецификация Go: 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
}


Читайте также:


Комментариев нет:

Отправить комментарий