Value.Call()
returns the return values of the function call as a []reflect.Value
. You may use the Value.Interface()
method to get the value represented by a reflect.Value
as an interface{}
value. From there, you may use type assertion to obtain values of different types.
Like in this simplified example:
var funcList = map[string]interface{}{
"test": func(ctx context.Context, data interface{}) (interface{}, error) {
return "test-result-data:" + fmt.Sprint(data), errors.New("test-error")
},
}
func Send(funcName string, data interface{}) (interface{}, error) {
f := reflect.ValueOf(funcList[funcName])
params := []reflect.Value{
reflect.ValueOf(context.Background()),
reflect.ValueOf(data),
}
res := f.Call(params)
ret := res[0].Interface()
var err error
if v := res[1].Interface(); v != nil {
err = v.(error)
}
return ret, err
}
Testing it:
result, err := Send("test", "testData")
fmt.Println(result, err)
Output:
test-result-data:testData test-error
But this is unnecessarily complex. You don't need to use reflection to call a function, you may call it directly and return the results directly, like this:
func Send2(funcName string, data interface{}) (interface{}, error) {
return funcList[funcName].(func(context.Context, interface{}) (interface{}, error))(
context.Background(), data,
)
}
Testing it:
result, err = Send2("test", "testData")
fmt.Println(result, err)
Output is the same. Try the examples on the Go Playground.