Назад к урокам

Анонимные-функции и замыкания в Go

Урок объясняет работу function literals в Go: анонимные функции, передача функции как аргумента, замыкания, захват внешних переменных и использование type alias для сигнатур функций.

Начинающий10 min

⚡ Function Literals, Anonymous Functions и Замыкания в Go

Function Literal --- это функция, объявленная прямо в выражении. В Go такие функции называют также анонимными функциями или замыканиями (closures). Они позволяют писать гибкий, компактный и динамичный код.


🔹 Что такое function literal?

Function literal - это функция без имени, которую можно:

  • присвоить переменной,
  • вызвать сразу,
  • передать как аргумент,
  • вернуть из другой функции.

Пример:

hello := func() {
    fmt.Println("Hello!")
}

hello()

🔹 Анонимная функция внутри функции

func helloWorld() {
    fmt.Printf("Hello, ")

    world := func() {
        fmt.Printf("World!\n")
    }

    world()
    world()
    world()
    world()
}

Вызывает вывод:

Hello, World!
World!
World!
World!

🔹 Функция как параметр

В Go можно передавать функции в функции:

func customMsg(fn func(m string), msg string) {
    msg = strings.ToUpper(msg)
    fn(msg)
}

Функция, возвращающая функцию:

func surround() func(msg string) {
    return func(msg string) {
        fmt.Printf("%.*s\n", len(msg), "-----")
        fmt.Println(msg)
        fmt.Printf("%.*s\n", len(msg), "-----")
    }
}

customMsg(surround(), "hello")

Результат:

-----
HELLO
-----

🔹 Замыкания (Closures)

Замыкание - это функция, которая захватывает переменные внешней области видимости.

Пример:

discount := 0.1

discountFn := func(subTotal float64) float64 {
    if subTotal > 100.0 {
        discount += 0.1
    }

    if discount > 0.3 {
        discount = 0.3
    }

    return discount
}

Замыкание сохраняет доступ к discount, даже после создания функции.


Пример использования замыкания

func calculatePrice(
    subTotal float64,
    discountFn func(subTotal float64) float64,
) float64 {
    return subTotal - (subTotal * discountFn(subTotal))
}

discount := 0.1
discountFn := func(subTotal float64) float64 {
    if subTotal > 100.0 {
        discount += 0.1
    }
    if discount > 0.3 {
        discount = 0.3
    }
    return discount
}

total := calculatePrice(120.0, discountFn)

🔹 Type Alias для функций

Для удобства тип функции можно вынести в алиас:

type DiscountFunc func(subTotal float64) float64

Теперь функция принимает читаемый тип:

func calculatePrice(
    subTotal float64,
    discountFn DiscountFunc,
) float64 {
    return subTotal - (subTotal * discountFn(subTotal))
}

✅ Итоги

  • Function literals - это функции без имени.
  • Их можно сохранять в переменные, передавать как аргументы и возвращать из функций.
  • Замыкания захватывают переменные из внешней области.
  • Type alias делает сигнатуры функций проще и понятнее.
Анонимные-функции и замыкания в Go | WebSchool