1

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

1 Answer 1

3

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)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks man ! And if I want to have a parameter in my function, do I pass this parameter in the {} of the reflect.Value or in the array of the Call ? Cuz I try to pass "test" for example and in the reflect.Value it says : cannot use "test" (type string) as type reflect.Value in slice literal. When I pass it in the array of Call, it says : invalid array bound "test". I don't understand how to pass a parameter like "test" for my function...
@Zouglou If the function has a string parameter, this is how you can call that: reflect.ValueOf(cmd).FieldByName("Echo").Call([]reflect.Value{reflect.ValueOf("someparam")})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.