Поведение отложенного на возвращаемое значение - PullRequest
0 голосов
/ 15 апреля 2020

В этом примере отложенная функция увеличивает возвращаемое значение I после возврата окружающей функции. Таким образом, эта функция возвращает 2:

func c() (i int) {
    defer func() { i++ }()
    return 1
}

Как получается, что это возвращает 2?

В блоге go Defer, Pani c и Recover

Отложенные функции могут считывать и присваивать именованные возвращаемые значения возвращаемой функции.

Я предполагаю, что намерение программиста - вернуть 1 в качестве результата, и удивляться, почему оно переопределяется, и какое дизайнерское решение стоит за ним.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Отложенные функции выполняются после того, как в этом операторе возврата заданы какие-либо параметры результата, но до того, как функция вернется к своему вызывающему.
Порядок выполнения:

func c() (i int) { // i = 0
    defer func() { i++ }()
    return 1  // i = 1
 // run deferred function here i++ => i = 2
}

См. пример для defer ключевое слово.

См. Defer_statements :

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

lock(l)
defer unlock(l)  // unlocking happens before surrounding function returns

// prints 3 2 1 0 before surrounding function returns
for i := 0; i <= 3; i++ {
    defer fmt.Print(i)
}

// f returns 42
func f() (result int) {
    defer func() {
        // result is accessed after it was set to 6 by the return statement
        result *= 7
    }()
    return 6
}
0 голосов
/ 15 апреля 2020

Отложенные анонимные функции могут получать доступ и изменять именованные возвращаемые параметры окружающей функции.

Из спецификации c:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...