Here is a code snippet -
type Gateway struct {
Svc1 svc1.Interface
Svc2 svc2.Interface
}
func (g *Gateway) GetClient(service string) interface{} {
ps := reflect.ValueOf(g)
s := ps.Elem()
f := s.FieldByName(strings.Title(service))
return f.Interface()
}
func (g *Gateway) Invoke(service string, endpoint string, args...
interface{}) []reflect.Value {
log.Info("Gateway.Invoke " + service + "." + endpoint)
inputs := make([]reflect.Value, len(args))
for i, _ := range args {
inputs[i] = reflect.ValueOf(args[i])
}
client := g.GetClient(service)
return reflect.ValueOf(client).Elem().MethodByName(endpoint).Call(inputs)
}
GetClient("svc1") works fine.
However, when I call Invoke("svc1", "endpoint1", someArg), it panics saying -
reflect: call of reflect.Value.Elem on struct Value
reflect.ValueOf(client).MethodByName(endpoint).Call(inputs) panics saying Call on a zero value.
There are a couple issues:
If svc1.Interface
is not a pointer or an interface, reflect.Value.Elem()
will panic (see https://golang.org/pkg/reflect/#Value.Elem)
If the endpoint
argument string of Invoke
doesn't match the capitalization of the target method, it will panic due to zero value (invalid reflect.Value
). Please note that the method you want to call must be exported.
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