The best I've come up with is to take a function def and return an interface, which will need type assertion afterwards:
func Wrapper(metaParams string, f func() (interface{}, string, error)) (interface{}, error) {
// your wrapper code
res, metaResults, err := f()
// your wrapper code
return res, err
}
Then to use this also takes a little work to function like a wrapper:
resInterface, err := Wrapper("data for wrapper", func() (interface{}, string, error) {
res, err := YourActualFuntion(whatever, params, needed)
metaResults := "more data for wrapper"
return res, metaResults, err
}) // note f() is not called here! Pass the func, not its results
if err != nil {
// handle it
}
res, ok := resInterface.(actualType)
if !ok {
// handle it
}
The upside is this is somewhat generic, can handle anything with 1 return type + error, and doesn't require reflection.
The downside is this takes a lot of work to use as it's not a simple wrapper or decorator.
func transform(f func(blah) blah) func(blah) blah
where you could pass infunc f(int) bool
like this:transform(f)
and have it return another function whose signature was alsofunc(int) bool
? – Ligialignaloesinterface{}
. It would then usereflect
to get the types of arguments and return value(s) of the function to be wrapped, and construct a call to it, then execute that call. I'm not surereflect
has all the tools to do that so I'm not posting this as an answer. But to be honest your question sounds like a case of the XY problem, so it would be better if you would narrow your problem statement down. – Ultimogeniture