Using this code as a template
package main
import "fmt"
type myStruct struct {
Value int
}
type counter int
func newFuncHandler(fn func(myStruct) error) (interface{}, *counter) {
count := counter(0)
newFn := func(e myStruct) error {
count = count + 1
return fn(e)
}
return newFn, &count
}
func main() {
fn := func(d myStruct) error {
// doing some stuff
return nil
}
handle, c := newFuncHandler(fn)
handleFn := handle.(func(d myStruct) error)
handleFn(myStruct{Value: 2})
handleFn(myStruct{Value: 2})
handleFn(myStruct{Value: 2})
handleFn(myStruct{Value: 2})
handleFn(myStruct{Value: 2})
fmt.Println(*c) // 5
}
how to modify newFuncHandler
so that it, given a function with unknown signature, returns a function with the same signature but with additional code for the function body. newFuncHandler
should not know of the myStruct
type
For example
func newFuncHandler(fn interface{}) (interface{}, *counter) {
count := counter(0)
// some reflection magic
// newFn has the same signature as fn (hardcoded in this case)
newFn := func(e myStruct) error {
// add custom code
count = count + 1
// call the original fn
return fn(e)
}
return newFn, &count
}
Use reflect.MakeFunc to make a function. Use Value.Call to call a function.
func newFuncHandler(v interface{}) (interface{}, *counter) {
count := counter(0)
fn := reflect.ValueOf(v)
newFn := reflect.MakeFunc(fn.Type(), func(args []reflect.Value) (results []reflect.Value) {
count = count + 1
return fn.Call(args)
})
return newFn.Interface(), &count
}