Can I create a new function using reflection in Go?

前端 未结 4 1684
醉话见心
醉话见心 2021-02-07 20:44

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{
          


        
相关标签:
4条回答
  • 2021-02-07 21:19

    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 and reflect.MakeFunc, which do exactly what you want.

    0 讨论(0)
  • 2021-02-07 21:20

    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:

    type MyService struct{
      Login func(username, password string) (sessionId int, err error)
      HelloWorld func(sessionId int) (hi string, err error)
    }
    
    autorpc.ImplementService(&MyService, MyServiceURL)
    session, err := MyService.Login(username, password)
    stringout, err := MyService.HelloWorld(session)
    
    0 讨论(0)
  • 2021-02-07 21:27

    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 using unsafe_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.

    0 讨论(0)
  • 2021-02-07 21:38

    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.

    0 讨论(0)
提交回复
热议问题