Тип функциональной переменной в Go
Я хочу написать функцию, которая принимает указатель на функцию любого типа. Я мог бы сделать:
func myFunc(f interface{})
... но это позволило бы нефункциональные значения. Есть ли способ, которым я могу ограничить тип для любой функции?
3 ответа
Предполагая, что вы буквально имеете в виду любую функцию, вы можете сделать переключение типа (которое будет конкретным):
switch v.(type) {
case func() int:
case func() string:
}
Или вы могли бы использовать reflect
Пакет для определения типа:
if reflect.TypeOf(v).Kind() != reflect.Func {
// error here
}
Это решение во время выполнения. Кроме этого, вы ничего не можете сделать. Недостатком этого является то, что компилятор не будет мешать кому-либо передавать нефункциональные значения.
Лично я бы избегал этого, и я ожидал бы конкретного прототипа func, например:
func myFunc(f func() string)
При этом вы с меньшей вероятностью будете иметь ошибки, когда компилятор знает, что это за типы.
Понятие "любая функция" может быть построено в Go в два этапа:
type MotherOfAllFuncs func()
Следующим шагом является завершение любой функции в замыкании, которое, как анонимный тип, совместимо с присваиванием MotherOfAllFuncs
,
func() {
anyFunction(with, any, parameters)
}
package main
import "fmt"
type f func()
func g(f f) {
f()
}
func h(i int) {
fmt.Println(21 * i)
}
func i() {
fmt.Println(314)
}
func main() {
g(func() { h(2) })
g(func() { i() })
}
Выход:
42
314
Функции первоклассных граждан в Go. Таким образом, они могут быть переданы и возвращены из функций, как и любой другой тип.
Вы можете определить свою функцию, чтобы взять функцию в качестве аргумента.
Читать далее - Функции первого класса и функции первого класса в Go.