First-class functions в Golang
Назначаем функции переменным
В языке Go вам разрешено назначать функцию переменной. Когда вы назначаете функцию переменной, тип переменной имеет тип функции, и вы можете вызвать эту переменную как вызов функции, как показано в приведенном ниже примере:
package main
import "fmt"
func main() {
num1, num2 := 10, 5
f1 := sub
fmt.Printf("\nType of f1 : %T\t\tResult: %d", f1, f1(num1, num2))
//Output : Type of f1 : func(int, int) int Result: 5
f2 := add
fmt.Printf("\nType of f2 : %T\t\tResult: %d", f2, f2(num1, num2))
//Output : Type of f2 : func(int, int) int Result: 15
f3 := mul
fmt.Printf("\nType of f3 : %T\t\tResult: %d", f3, f3(num1, num2))
//Output : Type of f3 : func(int, int) int Result: 50
f4 := div
fmt.Printf("\nType of f4 : %T\t\tResult: %d", f4, f4(num1, num2))
//Output : Type of f4 : func(int, int) int Result: 2
}
func sub(num1, num2 int) int {
return num1 - num2
}
func add(num1, num2 int) int {
return num1 + num2
}
func mul(num1, num2 int) int {
return num1 * num2
}
func div(num1, num2 int) int {
return num1 / num2
}
Передаём функции другим функциям
Переменные могут ссылаться на функции и передаваться в функции. Это значит, что Go позволяет передавать функции другим функциям.
package main
import "fmt"
func MathOperation(num1 int, num2 int, calculate func(int, int) int) int {
return calculate(num1, num2)
}
func main() {
num1, num2 := 10, 5
operation := MathOperation(num1, num2, add)
fmt.Println(operation) //This will print 15
operation = MathOperation(num1, num2, sub)
fmt.Println(operation) //This will print 5
operation = MathOperation(num1, num2, mul)
fmt.Println(operation) //This will print 50
operation = MathOperation(num1, num2, div)
fmt.Println(operation) //This will print 2
}
func sub(num1, num2 int) int {
return num1 - num2
}
func add(num1, num2 int) int {
return num1 + num2
}
func mul(num1, num2 int) int {
return num1 * num2
}
func div(num1, num2 int) int {
return num1 / num2
}
Объявляем типы функций
Можно объявить новый тип функции, чтобы сжать и уточнить код, который на неё ссылается. Типы функций и значения функций можно использовать и передавать так же, как и другие значения.
package main
import "fmt"
type operation func(num1 int, num2 int) int
func calculate(op operation, num1 int, num2 int) int {
return op(num1, num2)
}
func main() {
num1, num2 := 10, 5
result := calculate(add, num1, num2)
fmt.Println(result) // This will print 15
result = calculate(sub, num1, num2)
fmt.Println(result) // This will print 2
result = calculate(mul, num1, num2)
fmt.Println(result) // This will print 50
result = calculate(div, num1, num2)
fmt.Println(result) // This will print 5
}
func sub(num1, num2 int) int {
return num1 - num2
}
func add(num1, num2 int) int {
return num1 + num2
}
func mul(num1, num2 int) int {
return num1 * num2
}
func div(num1, num2 int) int {
return num1 / num2
}
Замыкания и анонимные функции
Анонимная функция, в Go её называют литералом функции, – это функция без имени. В отличие от обычных функций, литералы функций – это замыкания, так как они содержат ссылки на переменные в окружающей области.
Назначаем анонимную функцию переменной
Можно назначить анонимную функцию переменной, а затем использовать эту переменную, как и любую другую функцию.
package main
import "fmt"
var sayHelloWorld = func() {
fmt.Println("Hello World !")
}
func main() {
sayHelloWorld() // Hello World !
}
Назначаем анонимную функцию переменной в локальной области видимости
Переменная, которую вы объявляете, может находиться в области действия пакета или внутри функции, как показано в следующем списке.
package main
import "fmt"
func main() {
sayHelloWorld := func(userName string) {
fmt.Println("Hello", userName)
}
sayHelloWorld("Sharad")
}
Возвращаем функцию из другой функции
Анонимные функции могут пригодиться, когда нужно создать функцию на лету. Это относится и к возврату функции из другой функции.
package main
import (
"fmt"
)
func sayHello(name string) func() {
return func() {
fmt.Printf("Hello %s", name)
}
}
func main() {
f := sayHello("Sharad")
f()
}
Заключение
В этой статье мы узнали, что можно делать с функциями. Мы можем передавать функции в качестве параметров другой функции. Мы можем возвращать функцию из другой функции. Мы можем присваивать функции переменным. Мы можем определить типы функций. Когда функции рассматриваются как первоклассные, они открывают новые возможности для разделения и повторного использования кода. Чтобы создавать функции “на лету”, используйте анонимные функции с замыканиями.