Тип функции

Последнее обновление: 26.12.2017

Каждая функция имеет определенный тип, который складывается из списка типов параметров и списка типов возвращаемых рехультатов. Например, возьмем следующую функцию:

func add(x int, y int) int{
	return x + y
}

Эта функция представляет тип func(int, int) int. Этому же типу будет соответствовать следующая функция:

func multiply(x int, y int) int{
	return x * y
}

Хотя эта функция называется иначе, выполняет другие действия, но по типу параметров и по типу возвращаемого результата она соответствует выше указанному типу функции.

Возьмем еще одну функцию:

func display(message string){
	fmt.Println(message)
}

Эта функция имеет тип func(string). То есть опять же вначале идет слово func, а затем в скобках типы параметров. Так как функция не возвращает никакого результата, то соответственно возвращаемый тип не указывается.

Но какое значение имеет тип функции? Это значит, что мы можем определять переменные или параметры функций, которые будут представлять определенный тип функциии. То есть фактически переменная может быть функцией. Например:

package main

import "fmt"

func add(x int, y int) int{
	return x + y
}

func main() {
	
	var f func(int, int) int = add
	fmt.Println(f(3, 4))
	
	var x = f(4, 5)		// 9
	fmt.Println(x)
}

Здесь переменная f имеет тип func(int, int) int, то есть представляет любую функцию, которая принимает два параметра типа int и возвращает значение типа int. Поэтому мы можем присвоить этой переменной функцию add, которая соответствует данному типу:

var f func(int, int) int = add

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

var x = f(4, 5)	// 9

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

package main

import "fmt"

func add(x int, y int) int{ return x + y}
func multiply(x int, y int) int{ return x * y}

func display(message string){
	fmt.Println(message)
}

func main() {
	
	f := add		//или так var f func(int, int) int = add
	fmt.Println(f(3, 4))		// 7
	
	f = multiply	// теперь переменная f указывает на функцию multiply
	fmt.Println(f(3, 4))		// 12
	
	// f = display		// ошибка, так как функция display имеет тип func(string)
	
	var f1 func(string) = display	// норм 
	f1("hello")
}

Функции как параметры других функций

Также функция может передаваться в качестве параметра в другую функцию. Например:

package main

import "fmt"

func add(x int, y int) int {
	
	return x + y
}
func multiply(x int, y int) int {
	
	return x * y
}
func action(n1 int, n2 int, operation func(int, int) int){

	result := operation(n1, n2)
	fmt.Println(result)
}
func main() {
	
	action(10, 25, add)		// 35
	action(5, 6, multiply)	// 30
}

Здесь функция action принимает три параметра. Первые два параметра - числа, а третий параметр - функция, которая соответствует типу: func(int , int) int. То есть третий параметр представляет некоторое действие и может быть представлен любой функцией, которая принимает два значения типа int и возвращает также значение типа int. Для примера здесь как раз определены две подобных функции, которые соответствуют данному типу: add и multiply. Через имя параметра operation мы сможем вызывать данную функцию.

Или еще один пример:

package main

import "fmt"

func isEven(n int) bool{
	return n % 2 == 0
}
func isPositive(n int) bool{
	return n > 0
}

func sum(numbers []int, criteria func(int) bool) int{

	result := 0
	for _, val := range numbers{
		if(criteria(val)){
			result += val
		}
	}
	return result
}
func main() {
	
	slice := []int{-2, 4, 3, -1, 7, -4, 23}
	
	sumOfEvens := sum(slice, isEven)	// сумма четных чисел
	fmt.Println(sumOfEvens)				// -2
	
	sumOfPositives := sum(slice, isPositive)	// сумма положительных чисел
	fmt.Println(sumOfPositives)					// 37
}

Здесь функция sum вычисляет сумму элементов среза. Но н всех элементов, а только тех, которые соответствуют условию. Условие передается в виде функции в качестве второго параметра. Условие должно соответствовать функции типа func(int) bool. То есть функция должна принимать в качестве параметра значение типа int и возвращать значение типа bool, которое указывает, соответствовует ли переданное число условию.

Для примера здесь также определены две вспомогательные функции: isEven (возвращает true, если число четное) и isPositive (возвращает true, если число положительное). Эти функции соответствуют типу func(int) bool, поэтому их можно использовать в качестве условия.

Функция как результат другой функции

Функция также может возвращаться из другой функции в качестве результата:

package main

import "fmt"

func add(x int, y int) int{ return x + y}
func subtract(x int, y int) int{ return x - y}
func multiply(x int, y int) int{ return x * y}

func selectFn(n int) (func(int, int) int){
	if n==1 {
		return add
	}else if n==2{
		return subtract
	}else{
		return multiply
	}
}

func main() {
	
	f := selectFn(1)
	fmt.Println(f(3, 4))		// 7
	
	f = selectFn(3)
	fmt.Println(f(3, 4))		// 12
}

Здесь в зависимости от значения параметра функция selectFn возвращает одну из трех функций: add, subtract или multiply.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850