Типы довольно конкретные в Go.Вы можете попробовать
a := func(_ ...interface{}) {
fmt.Println("unprotected")
}
func (...interface{})
не означает «любая функция, которая принимает любое количество аргументов любого типа», это означает «только функцию, которая принимает переменное число аргументов интерфейса {}»
В качестве альтернативы вместо func(...interface{})
вы можете просто использовать interface{}
и пакет reflect
.См. http://github.com/hoisie/web.go для примера.
РЕДАКТИРОВАТЬ: В частности, это:
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 is
Protected
unprotected
Protected
hello
РЕДАКТИРОВАТЬ: ответить на обновление
Как я уже говорил выше, типы в Go довольно конкретны.Функция защиты возвращает тип func(...interface{})
, который никогда не будет назначаться на func(int)int
.Я думаю, что вы, вероятно, либо чрезмерно продумали свою проблему, либо неправильно ее поняли.Тем не менее, вот код крайне обескураженный кода, который заставил бы его работать.
Сначала измените защиту и верните значения:
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
}
}
Затем сделайте функцию преобразования:
func convert(f func(...interface{}) (func(int) int) {
return func(x int) int {
r := f(x)
return r[0].(int)
}
}
Тогда ваш звонок будет выглядеть так:
take_func_int_int(convert(b))
Но я обещаю, что это не то, что вы на самом деле хотите сделать.
Отойдите назад и попытайтесь переделатьпроблема.Я полностью убил безопасность типов в этих примерах.Что вы пытаетесь достичь?