В первом примере i
является (входящим) параметром. В операторе return
возвращаемое значение оценивается, и после этого выполняется отложенная функция, и увеличение значения i
на это не влияет на возвращаемое значение.
Во втором примере i
- это имя параметра результата. В операторе return
вы явно возвращаете значение i
, которое затем присваивается возвращаемому значению i
(это неоперация). Но отложенным функциям разрешено изменять значения возвращаемых «переменных», и если они это сделают, это повлияет на фактические возвращаемые значения.
Это станет понятнее, если мы добавим еще один пример:
func c2() (i int) {
defer func() { i++ }()
return 2
}
Эта функция вернет 3
, поскольку оператор return 2
назначит 2
для i
, тогда отложенная функция будет увеличивать его, и поэтому возвращаемое значение будет 3
. Попробуйте это на Go Playground . Соответствующая часть из Spec: операторы возврата:
Оператор return, который указывает результаты, устанавливает параметры результата перед выполнением любых отложенных функций.
Как правило, если функция (или метод) имеет именованные параметры результата, возвращаемые значения всегда будут значениями этих переменных, но не следует забывать, что оператор return
может назначать новые значения этим параметрам параметра и они могут быть изменены отложенными функциями после a return
оператора.
Это упомянуто в Spec: Отложенные заявления :
Например, если отложенная функция представляет собой литерал функции и окружающая функция имеет именованных параметров результата , которые находятся в области видимости внутри литерала, отложенная функция может получить доступ и изменить Параметры результата, прежде чем они будут возвращены.
Это также упоминается в блоге Отсрочка, паника и восстановление :
Отложенные функции могут читать и присваивать именованным возвращаемым функциям возвращаемые значения.
А также в Effective Go: Recover :
Если doParse
паникует, блок восстановления установит возвращаемое значение на nil
- отложенные функции могут изменять именованные возвращаемые значения.
См. Связанный вопрос: Как вернуть значение в функции Go, которая вызывает панику?