Страницы

Поиск по вопросам

понедельник, 10 февраля 2020 г.

Это анонимная функция, замыкание или что-то еще?

#golang


В документации к пакету нашел следующий код:

check:=func(err error) {
      if err != nill {
      log.Fatal(err)
      }
 }


Далее по коду  происходит вызов:

check(err)


как это правильно называется и для чего так делают? Почему нельзя было просто создать
обыкновенную функцию :

func check(err error) {
 if err != nil {
     log.Fatal(err)
     }
 }


и вызывать так же, как предыдущую
    


Ответы

Ответ 1



Это не анонимная функция и не замыкание. Это "функция как переменная" (function as value). Почему нельзя было просто создать обыкновенную функцию? Без контекста не ясно. Возможно переменная check переопределятся в момент выполнения. Анонимная функция Анонимная функция - функция, которая не может быть переопределена или вызвана повторно. Простыми словами, функция не имеет имени (анонимная) поэтому невозможно "назвать" или её повторно. например: I callItAsCallback(data, func(response string) { print(response) }) https://play.golang.org/p/Z8InpVJL9W II go func() { print("Hello!") } () https://play.golang.org/p/6Q0ITEMbta Функция как значение Функция как значение - функция, которая может быть переопределена или вызвана повторно. Функция имеет имя переменной в которой она определена. var check func() if time.Now().Second()%2 == 0 { check = func() { print("четное") } } else { check = func() { print("нечетное") } } check() Замыкание Замыкание - функция, которая хранит данные из области видимости родительской функции. Это как "характер" функции, ее особенность. Замыкания не возможны без функций "высшего порядка" (функции возвращающие другие функции). Исключение горутины. I В этом примере замыкание исользовано для инкапсуляции приватных значений. Не очень полезно в go. https://play.golang.org/p/7_ES6AKjlI II Класический пример примитивнейшей "фабрики"(паттерн проектирования). package main func main() { MakePizza("сыром!")() MakePizza("грибами!")() } func MakePizza(with string) func() { msg := "Пицца с " return func() { println(msg + with) } } Пицца с сыром! Пицца с грибами! https://play.golang.org/p/RuQV2b04nn Та же фабрика, но без замыкания. Это функция высшего порядка возвращающая анонимную функцию. https://play.golang.org/p/YhAM0kYWba III Ну и напоследок класический пример замыкания горутин в цикле. !!!! Этот пример заведомо неправильный! package main import "time" func main() { for i := 0; i < 10; i++ { go func() { println(i) }() } time.Sleep(time.Second) } 10 10 10 10 10 10 10 10 10 10 https://play.golang.org/p/jfHE9mGCV4 Правильный вариант, но это уже обычная анонимная функция. package main import "time" func main() { for i := 0; i < 10; i++ { go func(i int) { println(i) }(i) } time.Sleep(time.Second) } 0 1 2 3 4 5 6 7 8 9 https://play.golang.org/p/lPFt-_HRY6 Заключение Анонимные функции используются как callback(передаются как параметер в другую функцию) или как возвращаемое значение в функциях "высшего порядка". Функция как значение может быть использована как callback, как возвращаемое значение в функциях "высшего порядка" и для динамического переопределения логики внутри другой функции(неоправданно, но возможно). Функция высшего порядка - функция возврщающая другие функции, как с замыканием так и без. Замыкание - это эффект который может нести анонимная или "функция как значение" функция возвращаемая из функции высшего порядка или запущенная как горутина. Особенность в том, что функция может ссылаться на значения из родительской области видимости после "завершения" родительской функции.

Ответ 2



Все зависит от того как часто происходит вызов функции, возможно так автор пытался немного оптимизировать память. Если это огромный пакет, то возможно в этом есть смысл. Посмотри на пакет "encoding/json" там в процессе сериализации происходит составление кеша методов для каждого типа данных, что в дальнейшем ускоряет процесс кодирования / декодирования.

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

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