我的代码最后一个问题涉及到反射包中的.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
任何帮助将不胜感激!
答案 0 :(得分:9)
调用带有输入参数的函数
v
。例如,如果len(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)
答案 1 :(得分:7)
调用试图将零参数传递给期望一个参数的控制器(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
操作。但是你不要必须这样做才能发挥作用。)