Соответствующий раздел из спецификации: Типы функций .
Все остальные ответы здесь сначала объявляют новый тип, который является хорошим (практическим) и облегчает чтение вашего кода, но знайте, что это не является обязательным требованием.
Вы можете работать со значениями функций, не объявляя для них новый тип, как показано в следующем примере.
Объявление переменной типа функции, которая имеет 2 параметра типа float64
и имеет одно возвращаемое значение типа float64
, выглядит следующим образом:
// Create a var of the mentioned function type:
var f func(float64, float64) float64
Давайте напишем функцию, которая возвращает функцию сумматора. Эта функция сумматора должна принимать 2 параметра типа float64
и возвращать сумму этих двух чисел при вызове:
func CreateAdder() func(float64, float64) float64 {
return func(x, y float64) float64 {
return x + y
}
}
Давайте напишем функцию, которая имеет 3 параметра, первые 2 имеют тип float64
, а третий - значение функции, функция, которая принимает 2 входных параметра типа float64
и выдает значение типа float64
, И функция, которую мы пишем, вызовет значение функции, которое передается ей в качестве параметра, и использует первые 2 float64
значения в качестве аргументов для значения функции, и возвращает результат, который возвращает переданное значение функции:
func Execute(a, b float64, op func(float64, float64) float64) float64 {
return op(a, b)
}
Давайте посмотрим на наши предыдущие примеры в действии:
var adder func(float64, float64) float64 = CreateAdder()
result := Execute(1.5, 2.5, adder)
fmt.Println(result) // Prints 4
Обратите внимание, что, конечно, вы можете использовать Краткое объявление переменной при создании adder
:
adder := CreateAdder() // adder is of type: func(float64, float64) float64
Попробуйте эти примеры на Go Playground .
Использование существующей функции
Конечно, если у вас уже есть функция, объявленная в пакете с таким же типом функции, вы также можете использовать это.
Например, math.Mod()
имеет такой же тип функции:
func Mod(x, y float64) float64
Таким образом, вы можете передать это значение нашей Execute()
функции:
fmt.Println(Execute(12, 10, math.Mod)) // Prints 2
Печать 2
, потому что 12 mod 10 = 2
. Обратите внимание, что имя существующей функции действует как значение функции.
Попробуйте на Go Playground .
Примечание:
Обратите внимание, что имена параметров не являются частью типа, тип двух функций с одинаковыми параметрами и типами результатов идентичен независимо от имен параметров. Но знайте, что в списке параметров или результатов имена должны либо присутствовать, либо отсутствовать.
Так, например, вы также можете написать:
func CreateAdder() func(P float64, Q float64) float64 {
return func(x, y float64) float64 {
return x + y
}
}
Или:
var adder func(x1, x2 float64) float64 = CreateAdder()