Привет, товарищ интернет-пользователь, прежде чем мы начнем, в этой статье предполагается, что у вас есть следующие предварительные условия.

  • Вы знаете о функциях в go
  • иметь представление о локальном и глобальном масштабе
  • Настройте свой vsc для go-lang, потому что это будет восхитительный опыт с автозаполнением, линтингом и автоматическим импортом.

С этим покончено, перейдем к главному вопросу, юный падаван.

Что такое отсрочка?

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

  • В приведенном выше коде отложенной функцией является fmt.Println("Two") , поэтому эта функция будет выполняться после завершения выполнения окружающей функции, в нашем случае это было просто напечатать fmt.Println("Three"), как только это закончится, отложенная функция будет выполнена.
  • Следует отметить, что если у вас есть несколько ключевых слов defer в одной функции, они будут выполняться в порядке «первым пришел — последним», или в порядке FILO, простыми словами, в обратном порядке, в котором они были отложены.
  • Давайте немного сойдем с ума на секунду и добавим ключевое слово defer ко всему, что вы видите, попробуйте предсказать результат.

  • В приведенном выше коде, поскольку все отложено, ничего не выполняется до тех пор, пока элемент управления не достигнет строки 8, так как fmt.Println("Four") является последней отложенной функцией, она выполняется первой, другими словами, это не имеет большого значения, если вы хотите отложить функцию непосредственно перед завершением окружающей функции.
  • И так как fmt.Println("One") было отложено первым, оно было выполнено последним.
  • Следует отметить, что отложенная функция принадлежит окружающей функции, а не области действия блока, поэтому, если вы отложили функцию в блоке if или в цикле for, отложенная функция функция всегда будет выполняться после завершения окружающей функции, а не перед циклом или оператором if.

Хорошо, но что, если я хочу что-то вернуть из отложенной функции?

  • ну, вы не можете этого сделать, ваша функция должна быть такой, которая ничего не возвращает, или вы можете получить возврат и отложить его, но вам придется игнорировать возвращаемое значение.
  • Но в Go есть функция под названием named return, что делает вещи немного интереснее.

  • В строке выше, когда функция создается, returnVal равно 0, мы откладываем анонимную функцию, поэтому мы переходим к строке 15, там returnVal становится -1, наконец, наша функция запускается, и мы перезаписываем returnVal как 1000, и мы возвращаемся это значение.

Хорошо, теперь для закрытия

  • Замыкания — это значения функций, которые ссылаются на переменные, находящиеся вне рассматриваемой функции.
  • Этот фрагмент кода беззастенчиво украден из документации, потому что на самом деле его так легко понять.

  • что следует отметить: несмотря на то, что sum определено вне области действия анонимной функции возврата, переменная sum связана с ней, с другой копией каждый раз, когда adder() вызывается, чтобы быть точным.
  • здесь, поскольку каждый экземпляр анонимной функции, которая оказывается pos(i int) и neg(i int) , может быть вызван с другим параметром, они оба имеют свою собственную переменную sum под капотом, что позволяет им иметь разные выходные данные, как показано.

давайте смешать вещи!!

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

  • здесь vsc показывает, что переменная index будет захвачена, то есть адресное пространство, на которое ссылается index, будет привязано к функции, поэтому в выводе мы видим, что captured index is 4 печатается 4 раз, это связано с концепцией закрытия.
  • но в другом цикле, в строке 17, мы сохраняем значение, которое index содержит вместе с функцией, как указано в документах здесь,

Каждый раз, когда выполняется оператор defer, значение функции и параметры вызова оцениваются как обычно и сохраняются заново, но фактическая функция не вызывается.

Надеюсь, вы узнали что-то из этой статьи, если есть какие-либо неправильные предположения, сделанные от моего имени, пожалуйста, сообщите :), ничто не порадует меня больше, чем развеять мои неточные представления.

А пока я просто свяжу то, что помогло мне написать эту статью.

Спасибо за чтение и желаю вам отличного дня 😁

Первоначально опубликовано на https://toothsy.hashnode.dev.