7

我的代码遇到了最后一个问题,它涉及反射包中的 .Call 函数。

所以我正在打这样的电话:

params := "some map[string][]string"
in := make([]reflect.Value,0)
return_values := reflect.ValueOf(&controller_ref).MethodByName(action_name).Call(in)

我进行 .Call 的方法如下:

func (c *Controller) Root(params map[string][]string) map[string] string{}

我不太明白的是如何操作“in”变量以便正确地将我需要的映射传递给函数。我看到make()中的第二个参数是参数的长度?但我不太明白如何格式化变量以正确传递我的参数。我递归地遇到错误消息:

reflect: Call with too few input arguments

任何帮助将非常感激!

4

2 回答 2

14

来自Value.Call documentation

Callv使用输入参数 in 调用函数。例如, iflen(in) == 3表示v.Call(in)Go 调用v(in[0], in[1], in[2])

所以如果你想用一个参数调用一个函数,in必须包含一个reflect.Value正确的类型,在你的情况下map[string][]string

表达方式

in := make([]reflect.Value,0)

创建一个长度为 0 的切片。将其传递给Value.Call将导致您收到恐慌,因为您需要 1 个参数,而不是零。

正确的调用是:

m := map[string][]string{"foo": []string{"bar"}}

in := []reflect.Value{reflect.ValueOf(m)}

myMethod.Call(in)
于 2013-12-21T03:24:09.070 回答
10

该调用试图将零个参数传递给需要一个参数的控制器(in是一个空切片)。你需要做一些更像in := []reflect.Value{reflect.ValueOf(params)}.

您也可以.Interface()在找到方法后调用,然后使用类型断言来获取func可以直接调用的方法:

// get a reflect.Value for the method
methodVal := reflect.ValueOf(&controller_ref).MethodByName(action_name)
// turn that into an interface{}
methodIface := methodVal.Interface()
// turn that into a function that has the expected signature
method := methodIface.(func(map[string][]string) map[string]string)
// call the method directly
res := method(params)

(然后你甚至可以缓存 method在一个以方法名称为键的映射中,这样你就不必reflect在下一次调用时进行操作。但你不必为了它工作而这样做。)

于 2013-12-21T03:23:55.093 回答