Reputation: 129
I want to call a field of my structure with a string, so I checked out and I saw that I need to use the reflection package. Here's my code:
package main
import (
"fmt"
"reflect"
)
type cmd struct{
echo func() (string,error)
}
func main() {
cmd:=cmd{
echo : func () (string,error){
return "test", nil
},
}
fmt.Println(reflect.ValueOf(&cmd).MethodByName("echo").Call([]reflect.Value{}))
}
And when I want to build it, it panics like :
panic: reflect: call of reflect.Value.Call on zero Value
goroutine 1 [running]:
reflect.flag.mustBe(...)
c:/go/src/reflect/value.go:208
reflect.Value.Call(0x0, 0x0, 0x0, 0xc0000c7f50, 0x0, 0x0, 0x0, 0x0, 0xc000086058)
c:/go/src/reflect/value.go:319 +0x174
I do not understand the []reflect.Value{}
, why do I need to use this on the line :
reflect.ValueOf(&cmd).MethodByName("echo").Call([]reflect.Value{})
Hope someone can help ! :D
Chris
Upvotes: 1
Views: 2091
Reputation: 417552
cmd.echo
is not a method. It's a field of function type. Access it using Value.FieldByName()
.
And only exported fields can be accessed, rename it to Echo
.
And you have to pass a non-pointer cmd
, or if you pass &cmd
, you have to call Value.Elem()
.
Working example:
type cmd struct {
Echo func() (string, error)
}
cmd := cmd{
Echo: func() (string, error) {
return "test", nil
},
}
fmt.Println(reflect.ValueOf(cmd).FieldByName("Echo").Call([]reflect.Value{}))
This outputs (try it on the Go Playground):
[test <error Value>]
Also note that if the function does not have parameters, you pass nil
to Value.Call()
:
reflect.ValueOf(cmd).FieldByName("Echo").Call(nil)
Upvotes: 3