Been having one last issue with my code which involves the .Call function in the reflect package.
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:
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. I see that the second parameter in the make() is the length of the parameter? 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
:
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])
.
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
.
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.
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). You need to do something more like 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:
// 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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With