Wednesday, October 05, 2016

How to convert from a Go reflect.Value to the actual type

//Author Geoffrrey Hendrey
//Here we dynamically invoke a method, passing the method the input, whose type we don't know. We know the method returns two things, a value and an errror.
//(multiple return values). This code shows how we grab the error, which
//is the second return value of the method, check it it is not nil, and if not nil type-assert it to an actual error (line 11). They key is
//on line 11 where we extract the interface() from the errReflect, which is reflect.Value. Once we have an interface{} we can do the type-assertion.
func invokeMethod(method reflect.Value, input interface{}) (resp interface{}, err error) {
in := []reflect.Value{reflect.ValueOf(input)}
returnValuesFromClientCall := method.Call(in)
errReflect := returnValuesFromClientCall[1] //this is the error return value from the call above
if !errReflect.IsNil() { //if there was an error
ifc := errReflect.Interface()
err := ifc.(error)
log.Errorf("method call returned error: %s", err.Error())
return nil, err
}
return returnValuesFromClientCall[0].Interface(), nil
}