I try to write a function which takes any other function and wraps a new function around it. This is what I have tried so far:
package main
import (
"fmt"
)
func protect (unprotected func (...interface{})) (func (...interface{})) {
return func (args ...interface{}) {
fmt.Println ("protected");
unprotected (args...);
};
}
func main () {
a := func () {
fmt.Println ("unprotected");
};
b := protect (a);
b ();
}
When I compile this I get the error:
cannot use a (type func()) as type func(...interface { }) in function argument
Why is a function without arguments not compatible to a function with a variable number of arguments? What can I do to make them compatible?
Update:
The protected function should be compatible with the original:
func take_func_int_int (f func (x int) (y int)) (int) {
return f (1)
}
func main () {
a := func (x int) (y int) {
return 2 * x
}
b := protect (a)
take_func_int_int (a)
take_func_int_int (b)
}
Types are pretty concrete in Go. You could try
func (...interface{})does not mean “any function that takes any number of any kind of arguments”, it means “only a function which takes a variable number of interface{} arguments”Alternatively rather than
func(...interface{})you can just useinterface{}and thereflectpackage. See http://github.com/hoisie/web.go for an example.EDIT: Specifically, this:
Ouput is
EDIT: To answer the update
Like I said above, types are pretty concrete in Go. The protect function returns a type
func(...interface{})which will never be assignable tofunc(int)int. I think you’re probably either over-engineering your problem or misunderstanding it. However, here’s a highly discouraged code snippet that would make it work.First change protect to also return values:
Then make a convert function:
Then your call would look like
But I promise this isn’t what you actually want to do.
Step back and try to rework the problem. I’ve completely killed type-safety in these examples. What are you trying to accomplish?