Урок объясняет работу function literals в Go: анонимные функции, передача функции как аргумента, замыкания, захват внешних переменных и использование type alias для сигнатур функций.
Function Literal --- это функция, объявленная прямо в выражении. В Go такие функции называют также анонимными функциями или замыканиями (closures). Они позволяют писать гибкий, компактный и динамичный код.
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
-----
Замыкание - это функция, которая захватывает переменные внешней области видимости.
Пример:
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 DiscountFunc func(subTotal float64) float64
Теперь функция принимает читаемый тип:
func calculatePrice(
subTotal float64,
discountFn DiscountFunc,
) float64 {
return subTotal - (subTotal * discountFn(subTotal))
}