Types are pretty specific in Go. You can try
a := func(_ ...interface{}) { fmt.Println("unprotected") }
func (...interface{}) does not mean "any function that takes any number of any arguments", it means "only a function that takes a variable number of interface arguments {}"
Alternatively, instead of func(...interface{}) you can simply use the interface{} and reflect package. For an example, see http://github.com/hoisie/web.go .
EDIT: In particular, this:
package main import ( "fmt" "reflect" ) func protect(oldfunc interface{}) (func (...interface{})) { if reflect.TypeOf(oldfunc).Kind() != reflect.Func { panic("protected item is not a function") } return func (args ...interface{}) { fmt.Println("Protected") vargs := make([]reflect.Value, len(args)) for n, v := range args { vargs[n] = reflect.ValueOf(v) } reflect.ValueOf(oldfunc).Call(vargs) } } func main() { a := func() { fmt.Println("unprotected") } b := func(s string) { fmt.Println(s) } c := protect(a) d := protect(b) c() d("hello") }
Ouput -
Protected unprotected Protected hello
EDIT: to respond to the update
As I said, types are pretty specific in Go. The security function returns a type of func(...interface{}) that will never be assigned to func(int)int . I think that you are probably underestimating your problem too much or underestimating it. However, there is a very discouraged piece of code that will make it work.
The first change also protects the return values:
func protect(oldfunc interface{}) (func (...interface{}) []interface{}) { if reflect.TypeOf(oldfunc).Kind() != reflect.Func { panic("protected item is not a function") } return func (args ...interface{}) []interface{} { fmt.Println("Protected") vargs := make([]reflect.Value, len(args)) for n, v := range args { vargs[n] = reflect.ValueOf(v) } ret_vals := reflect.ValueOf(oldfunc).Call(vargs) to_return := make([]interface{}, len(ret_vals)) for n, v := range ret_vals { to_return[n] = v.Interface() } return to_return } }
Then execute the conversion function:
func convert(f func(...interface{}) (func(int) int) { return func(x int) int { r := f(x) return r[0].(int) } }
Then your call will look like
take_func_int_int(convert(b))
But I promise that this is not what you really want to do.
Go back and try to redo the problem. In these examples, I completely killed type safety. What are you trying to accomplish?