The golang’s function is a code block like C’s, but it can also be assigned to a variable as its other types.
If you are not familiar with the function, Codewalk: First-Class Functions in Go should be a good starting point for you. Already known it? Let’s go on.
First of all, look at this PHP codes:
It will print:
mikespook@mikespook-laptop:~/Desktop$ php foobar.php |
It is very useful for calling a function with name matching.
So, is it possible to call a function by its name in Golang?
As a static, compiled programming language, the answer is No … and YES!
You can not do this in Golang:
You can do:
funcs := map[string]func() { "foobar" :foobar} |
But here’s a limitation that the map only work with the prototype “func()”, no input parameters and return arguments.
If you want to call some functions have different function’s prototypes, the interface{} should be used.
Yep! interface{}, like the void pointer in C. Remember that? No? Never mind! Read this: The Go Programming Language Specification:Interface types.
Then we could add functions with different prototypes into one map:
funcs := map[string]interface{}{ "foo" :foo, "bar" :bar} |
How to call a function in the map? like this?
NO! It does not work! You can not call a function stored in a empty interface variable directly.
Dadadada…
Reflection comes to us! It is a package called “reflect” in Golang. Do you know reflection already?
If not, just read this: Laws of reflection.
func Call(m map[string]interface{}, name string, params ... interface{}) (result []reflect.Value, err error) { |
f = reflect.ValueOf(m[name]) |
if len(params) != f.Type().NumIn() { |
err = errors.New( "The number of params is not adapted." ) |
in := make([]reflect.Value, len(params)) |
for k, param := range params { |
in[k] = reflect.ValueOf(param) |
Call(funcs, "bar" , 1, 2, 3) |
Reflecting the function variable, use reflect.Call to call it and pass parameters into it at the same time.
Nothing could be hard to understand.
I’ve done a package for this functional: https://bitbucket.org/mikespook/golib/src/27c65cdf8a77/funcmap.
Hope this helps. Have a good time, gophers!
Leave a Reply