douwang4374 2017-10-06 13:47
浏览 432
已采纳

Golang获得反射调用的结果

I'm making a reflection function call but I'm currently stuck on trying to get the return values.

Example code:

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
}

How do I get the return values from "value" and return them correctly?

Cheers

  • 写回答

1条回答 默认 最新

  • dpa55065 2017-10-06 14:19
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历