英文:
Reflection - method call panics with "call of reflect.Value.Elem on struct Value"
问题
以下是代码段的翻译:
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") 的调用正常工作。
然而,当我调用 Invoke("svc1", "endpoint1", someArg) 时,它会抛出 panic 错误:
reflect: call of reflect.Value.Elem on struct Value
reflect.ValueOf(client).MethodByName(endpoint).Call(inputs) 抛出 panic 错误,提示在零值上调用 Call 方法。
英文:
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.
答案1
得分: 11
有几个问题:
-
如果
svc1.Interface
不是指针或接口类型,reflect.Value.Elem()
会引发恐慌(参见https://golang.org/pkg/reflect/#Value.Elem)。 -
如果
Invoke
的endpoint
参数字符串与目标方法的大小写不匹配,将会因为零值(invalid reflect.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 ofInvoke
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论