[英]How to properly use .Call in reflect package
Been having one last issue with my code which involves the .Call function in the reflect package. 我的代码最后一个问题涉及到反射包中的.Call函数。
So I'm making a call such as this: 所以我正在打这样的电话:
params := "some map[string][]string"
in := make([]reflect.Value,0)
return_values := reflect.ValueOf(&controller_ref).MethodByName(action_name).Call(in)
where the method I'm making the .Call to is as follows: 我正在制作.Call的方法如下:
func (c *Controller) Root(params map[string][]string) map[string] string{}
What I don't quite understand is how to manipulate the "in" variable in order to properly pass the map I need to into the function. 我不太明白的是如何操纵“in”变量以便将我需要的地图正确传递到函数中。 I see that the second parameter in the make() is the length of the parameter? 我看到make()中的第二个参数是参数的长度? But I don't quite understand how to format the vars in order to properly pass in my parameter. 但我不太明白如何格式化变量以正确传递我的参数。 I am recursively running into the error message: 我递归地运行错误消息:
reflect: Call with too few input arguments
Any help would be much appreciated! 任何帮助将非常感激!
From the Value.Call documentation
: 从Value.Call documentation
:
Call calls the function
v
with the input arguments in. For example, iflen(in) == 3
,v.Call(in)
represents the Go callv(in[0], in[1], in[2])
. 调用带有输入参数的函数v
。例如,如果len(in) == 3
,则v.Call(in)
表示Go调用v(in[0], in[1], in[2])
。
So if you want to call a function with one parameter, in
must contain one reflect.Value
of the right type, in your case map[string][]string
. 所以,如果你想调用一个函数带有一个参数, in
必须包含一个reflect.Value
正确类型的,你的情况map[string][]string
。
The expression 表达方式
in := make([]reflect.Value,0)
creates a slice with length 0. Passing this to Value.Call
will result in the panic you receive as you need 1 parameter, not zero. 创建一个长度为0的切片。将此Value.Call
传递给Value.Call
将导致您收到的恐慌,因为您需要1个参数,而不是零。
The correct call would be: 正确的电话会是:
m := map[string][]string{"foo": []string{"bar"}}
in := []reflect.Value{reflect.ValueOf(m)}
myMethod.Call(in)
The call is trying to pass zero parameters to a controller that expects one param ( in
is an empty slice). 该调用试图将零参数传递给期望一个参数的控制器( in
是一个空切片)。 You need to do something more like in := []reflect.Value{reflect.ValueOf(params)}
. 你需要做更多的事情in := []reflect.Value{reflect.ValueOf(params)}
。
You could also call .Interface()
once you've found the method, then use type assertion to get a func
you can call directly: 一旦找到方法,你也可以调用.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)
(Then you could even cache method
in a map keyed by method name, so you wouldn't have to do reflect
operations next call. But you don't have to do that for it to work.) (然后你甚至可以在方法名称键入的地图中缓存 method
,因此你不必在下次调用时进行reflect
操作。但是你不必这样做才能使它工作。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.