Golang得到了一个反射调用的结果

时间:2017-10-06 13:47:46

标签: go reflection

我正在进行反射函数调用,但我目前仍在尝试获取返回值。

示例代码:

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
}

如何从“值”获取返回值并正确返回?

干杯

1 个答案:

答案 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上的示例。