Используйте interface{}
для представления функции любого типа. Не существует более точного типа, который работает с любой функцией.
Используйте пакет отражение для реализации partial
.
func partial(f interface{}, arg interface{}) interface{} {
v := reflect.ValueOf(f)
t := v.Type()
var in []reflect.Type
for i := 1; i < t.NumIn(); i++ {
in = append(in, t.In(i))
}
var out []reflect.Type
for i := 0; i < t.NumOut(); i++ {
out = append(out, t.Out(i))
}
var va reflect.Value
if arg != nil {
va = reflect.ValueOf(arg)
} else {
// Support `nil` as partial argument.
va = reflect.Zero(t.In(0))
}
return reflect.MakeFunc(reflect.FuncOf(in, out, t.IsVariadic()),
func(args []reflect.Value) []reflect.Value {
return v.Call(append([]reflect.Value{va}, args...))
}).Interface()
}
Используйте его следующим образом:
addToFive := partial(sum, 5).(func(int) int)
fmt.Println(addToFive(1))
Запустите его на игровой площадке .
Я рекомендую использовать замыкание для создания партиалов вместо функции partial
в этом ответе. Закрытие более эффективно и позволяет избежать хитрого отражения кода.
addToFive := func(x int) int { return sum(5, x) }
fmt.Println(addToFive(1))