Reflection 我可以在Go中使用反射创建新函数吗?

Reflection 我可以在Go中使用反射创建新函数吗?,reflection,go,Reflection,Go,我有一个想法,在Go中使用接口来定义RPC样式的接口。因此,对于给定的服务,我可以创建如下接口: type MyService interface{ Login(username, password string) (sessionId int, err error) HelloWorld(sessionId int) (hi string, err error) } 我想做的是使用反射来实现该接口,将方法调用转换为RPC调用,封送输入参数,并将结果解组回方法的输出。我知道如果我可以得

我有一个想法,在Go中使用接口来定义RPC样式的接口。因此,对于给定的服务,我可以创建如下接口:

type MyService interface{
  Login(username, password string) (sessionId int, err error)
  HelloWorld(sessionId int) (hi string, err error)
}

我想做的是使用反射来实现该接口,将方法调用转换为RPC调用,封送输入参数,并将结果解组回方法的输出。我知道如果我可以得到输入参数的[]接口{},我可以使用反射来进行服务调用。但是,我看不到任何使用反射动态创建值的方法,该值将通过使用函数调用我的反射来实现接口。有人知道这样做的方法吗,即使使用不安全的方法?

您不能通过反射创建带有附加方法的类型,因为无法实例化该类型的对象

通过
unsafe
软件包,您可能会通过大量黑客手段实现这一点。但即使这样,也会带来巨大的痛苦

如果你详细阐述了你试图解决的问题,社区可以想出其他解决方法


编辑(2015年7月23日):从Go 1.5开始,有
reflect.FuncOf
reflect.MakeFunc
,它们完全可以实现您想要的功能。

我认为,如果能够完全实现
reflect.Type
接口,您可能无法实现(未报告的方法)。然后,也许可以通过使用
unsafe\u New
实例化自定义类型

总而言之,这样做不是一个好主意

你想要的第二个最好的方法可能是使用类似的东西。您可以使用gob作为中间语言,使用反射从接口读取方法,将它们编写为gob,并将创建的gob代码解码为真正的Go对象。但我不确定这是否值得

大多数情况下,通过在客户端手动实现接口,您会更安全
和转发方法调用。

反射包似乎将获得在Go 1.1:中创建新的任意类型函数的能力

(以下是对@nemo的回应)

可以创建结构类型,而不是接口:

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)

由于语言的静态特性,目前无法在Go中动态实现接口

我理解您想要实现的目标,还有其他一些场景也将受益于更高级的反射功能(例如,用于单元测试的良好模拟框架)


也就是说,有一种方法可以解决这个问题。您可以编写自己的工具,生成包含给定RPC接口实现的Go源代码文件

您必须使用该库以及其他库来解析和处理源接口


沿着这条路走下去(工具;可以用作参考),我可以说它一点也不有趣和容易。尽管如此,最终的结果还是可以接受的,因为Go提供了
Go:generate
功能,这至少使界面更改后重新运行工具变得更加容易。

unsafe\u New
运行时
包中定义的函数,由
反射
包用于创建新对象。例如,在
reflect
函数中使用。问题的关键在于,Go接口可能是描述某种RPC服务的一种很好的方式。但是,正如您所确认的,今天(对于大型接口),必须创建大量样板代码,才能通过RPC调用实现接口。我意识到样板代码可以通过一些外部工具自动创建,但是如果能够通过反射来完成这一切,那将是非常酷的。reflect.MakeFunc自Go 1.1以来已存在。reflect.FuncOf是在1.5中添加的,但不支持创建实现任意接口所需的方法。我们需要的是能够创建新的“命名”类型,并在运行时定义这些类型的方法。既然这件事有悬赏,你应该把其中一件作为你的答案。你不会让任何人说任何其他的话。但这不会给你一个类型关联。因此,没有接口的任意实现。