I want to write a function which takes a pointer to any type of function. I could do:
func myFunc(f interface{})
...but that would allow non-function values. Is there any way I can restrict the type to any function?
Assuming you literally mean any function, you can either do a type switch (which would be specific):
switch v.(type) {
case func() int:
case func() string:
}
Or you could use the reflect package to determine the type:
if reflect.TypeOf(v).Kind() != reflect.Func {
// error here
}
This is a runtime solution. Other than that, there's nothing else you can do. The downside about this is the compiler won't stop someone from passing a non-function value.
Personally I would avoid doing this, and I would expect a specific func prototype, like:
func myFunc(f func() string)
With this you're less likely to have errors when the compiler knows what the types are.
The concept of "any function" can be constructed in Go in two steps:
type MotherOfAllFuncs func()
The next step is to to wrap any function in a closure, which, as an anonymous type, is assignment compatible with 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() })
}
Output:
42
314
Functions are first class citizens in Go. So they can be passed to and returned from functions like any other type.
You can define your function to take function as its argument.
Read more - First class functions and First class functions in Go.
func takesFunc(f func()) and be able to pass in ANY function (regardless of argument and return types). What you're saying will allow me to accept one particular TYPE of function (ie, func(int) int or func(bool) (string, int)), but not any arbitrary function type.
interface{}, so this is the best you can do.