我正在进行反射函数调用,但我目前仍在尝试获取返回值。
示例代码:
func (c *Client) Send(funcName protoFunction, data interface{}) (interface{}, error) {
funcList := c.GetProtoFuncList()
ctx := context.Background()
f := reflect.ValueOf(funcList[funcName.String()])
vals := make([]reflect.Value, 2)
vals[0] = reflect.ValueOf(ctx)
vals[1] = reflect.ValueOf(data)
value := f.Call(vals)
log.Debug(value)
return nil, nil
}
如何从“值”获取返回值并正确返回?
干杯
答案 0 :(得分:2)
Value.Call()
将函数调用的返回值作为[]reflect.Value
返回。您可以使用Value.Interface()
方法将reflect.Value
表示的值作为interface{}
值。从那里,您可以使用type assertion获取不同类型的值。
就像在这个简化的例子中一样:
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
}
测试它:
result, err := Send("test", "testData")
fmt.Println(result, err)
输出:
test-result-data:testData test-error
但这不必要地复杂。您不需要使用反射来调用函数,您可以直接调用它并直接返回结果,如下所示:
func Send2(funcName string, data interface{}) (interface{}, error) {
return funcList[funcName].(func(context.Context, interface{}) (interface{}, error))(
context.Background(), data,
)
}
测试它:
result, err = Send2("test", "testData")
fmt.Println(result, err)
输出是一样的。试试Go Playground上的示例。