John Dowling
John Dowling

Reputation: 612

Reflect return values

I am having a few issues with return values on a call, I have the below

err := reflect.ValueOf(a.a).MethodByName(gatherList[x]).Call([]reflect.Value{})

The issue is with the return value which is nil

I can't do the usual error check as I get the following.

cannot convert nil to type reflect.Value

when I try to print the contents of err i get;

[<error Value>]

not really sure how to move forward with this error check, any help would be great.

Upvotes: 3

Views: 6256

Answers (1)

icza
icza

Reputation: 418585

Value.Call() calls the function represented by the value, and returns a slice which represents the return values of the function (it must be a slice as in Go functions and methods may have multiple return values). The returned slice is of type []reflect.Value (so its elements are of type reflect.Value and not interface{}).

If your function or method returns an error too, you may examine the corresponding element in the returned slice. You may use Value.Interface() to obtain the value as an interface{} from the reflect.Value value.

See this example:

type My int

func (m My) Get() error {
    return nil
}

func (m My) GetError() error {
    return fmt.Errorf("artificial error")
}

Calling My.Get() never returns an error (it returns nil), and calling My.GetError() always returns a non-nil error.

Calling them with reflection:

methods := []string{"Get", "GetError"}
for _, m := range methods {
    result := reflect.ValueOf(My(0)).MethodByName(m).Call(nil)
    err := result[0].Interface()
    if err == nil {
        fmt.Println("No error returned by", m)
    } else {
        fmt.Printf("Error calling %s: %v", m, err)
    }
}

Output (try it on the Go Playground):

No error returned by Get
Error calling GetError: artificial error

Upvotes: 7

Related Questions