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()
}

Заключение

В этой статье мы узнали, что можно делать с функциями. Мы можем передавать функции в качестве параметров другой функции. Мы можем возвращать функцию из другой функции. Мы можем присваивать функции переменным. Мы можем определить типы функций. Когда функции рассматриваются как первоклассные, они открывают новые возможности для разделения и повторного использования кода. Чтобы создавать функции “на лету”, используйте анонимные функции с замыканиями.

Ответить