I have an idea to use interfaces in Go to define RPC style interfaces. So for a given service, I might create an interface like this:
type MyService interface{
Login(username, password string) (sessionId int, err error)
HelloWorld(sessionId int) (hi string, err error)
}
What I would like to do is use reflection to implement that interface, translating method calls into RPC calls, Marshaling the input parameters, and Unmarshaling the results back into the output of the method. I know that if I can get a []interface{} of the input parameters I can use reflection to make the service call. However I don't see any way to use reflection to dynamically create a value that would implement the interface by calling my reflection-using functions. Does anyone know of a way to do this, even using unsafe?
It appears that the reflect package will gain the ability to create new arbitrarily typed functions in Go 1.1: reflect.MakeFunc.
(the following added in response to @nemo)
Instead of an interface, one could create a struct type:
I think it might be possible to achieve what you want if one could fully implement the
reflect.Type
interface, which you can't (unexported methods). Then it could, maybe, be possible to instantiate your custom type by usingunsafe_New
.All in all it is not a good idea to do so.
The next best thing to what you want is probably to use something like gob. You can use gob as intermediate language, read the methods from your interface using reflection, write them as gob and decode the created gob code to real Go objects. But I'm not sure if that's worth it.
Most of the time you're safer by manually implementing your interface on the client side and forwarding the method calls.
You can not create a type with attached methods via reflection, as to instantiate an object of that type.
You could possibly achieve this with a lot of hackery through the
unsafe
package. But even then, it'd be a massive pain.If you elaborated more on the problem you're trying to solve, the community could come up with alternatives ways of solving it.
Edit (23. July 2015): starting with Go 1.5 there's
reflect.FuncOf
andreflect.MakeFunc
, which do exactly what you want.Due to the static nature of the language, there is no way to implement an interface dynamically in Go at this point in time.
I understand what you want to achieve and there are other scenarios that would also benefit of a more advanced reflection capability (e.g. a good mocking framework for unit tests)
That said, there is a way that you could workaround this problem. You could write your own tool which generates a Go source code file containing a given RPC implementation of an interface.
You would have to use the AST library, as well as others, to parse and process the source interface.
Having gone down that path (gostub tool; can use as reference), I can say it is not at all fun and easy. Still, the end result is bearable since Go provides the
go:generate
functionality, which at least makes rerunning the tool, once an interface has changed, a tad easier.