![](/img/trans.png)
[英]Golang - Why this error happened in ServeHTTP Function : reflect: call of reflect.Value.Call on zero Value
[英]panic: reflect: call of reflect.Value.Call on zero Value
我正在尝试使用反射来根据用户输入进行动态 function 调用。 我正在收集这样的用户输入:
func main() {
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("> ")
command, _ := reader.ReadString('\n')
runCommandFromString(command)
}
}
这就是命令被解析出来的方式
func stringCommandParser(cmd string) *Command {
cmdParts := strings.Split(
strings.TrimSpace(cmd),
" ",
)
return &Command{
Name: cmdParts[0],
Args: cmdParts[1:],
}
}
func runCommandFromString(cmd string) {
command := stringCommandParser(cmd)
c := &Commander{}
f := reflect.ValueOf(&c).MethodByName(command.Name)
inputs := []reflect.Value{reflect.ValueOf(command)}
f.Call(inputs)
}
commands.go 文件如下所示
type Command struct {
Name string
Args []string
}
type Commander struct {}
func (c Commander) Hello(cmd Command) {
fmt.Println("Meow", cmd.Args)
}
当我运行该程序时,我得到一个提示,然后我运行一个名为“Hello”的命令和一个名为“world”的参数。 我希望出现“Meow [World]”或类似的东西。 像这样:
> Hello world
Meow world
相反,我得到的是一个看起来像这样的恐慌:
> Hello world
panic: reflect: call of reflect.Value.Call on zero Value
goroutine 1 [running]:
panic(0x123360, 0xc420014360)
/Users/parris/.gvm/gos/go1.7.4/src/runtime/panic.go:500 +0x1a1
reflect.flag.mustBe(0x0, 0x13)
/Users/parris/.gvm/gos/go1.7.4/src/reflect/value.go:201 +0xae
reflect.Value.Call(0x0, 0x0, 0x0, 0xc420055e00, 0x1, 0x1, 0x0, 0x0, 0x0)
/Users/parris/.gvm/gos/go1.7.4/src/reflect/value.go:300 +0x38
main.runCommandFromString(0xc42000c8a0, 0xc)
/Users/parris/Projects/distro/main/utils.go:26 +0x1a0
main.main()
/Users/parris/Projects/distro/main/main.go:14 +0x149
exit status 2
我怎样才能解决这个问题? 另外,这是怎么回事?
您可能想在使用之前检查reflect.ValueOf
返回的内容。
在这种情况下,您将获得一个 nil 值,因为reflect 看不到未导出的函数。 hello
以小写字母开头,因此不会导出。
另外,你在这里提出了太多的指针,我怀疑你需要做reflect.ValueOf(c)
。 您同时在做和调试太多的事情。 制作一个简单的工作示例并从那里继续调试。
只需在您的代码中做两个更改。 首先将reflect.ValueOf(&c) 更改为reflect.ValueOf(c) 其次将reflect.ValueOf(command) 更改为reflect.ValueOf(*command)
这是代码workingcode
调用 Kind() 检查
type Header struct {
Token string
}
type Request struct {
Header
}
func requestedToken(request interface{}) string {
requestValue := reflect.ValueOf(request)
header := requestValue.FieldByName("Header12")
if header.Kind() == 0 {
return "" //Return here
}
token := header.FieldByName("Token")
if token.Kind() == 0 {
return ""
}
return token.String()
}
您需要将runCommandFromString
更改为RunCommandFromString
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.