Reflection 我可以在Go中使用反射创建新函数吗?
我有一个想法,在Go中使用接口来定义RPC样式的接口。因此,对于给定的服务,我可以创建如下接口: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调用,封送输入参数,并将结果解组回方法的输出。我知道如果我可以得
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中添加的,但不支持创建实现任意接口所需的方法。我们需要的是能够创建新的“命名”类型,并在运行时定义这些类型的方法。既然这件事有悬赏,你应该把其中一件作为你的答案。你不会让任何人说任何其他的话。但这不会给你一个类型关联。因此,没有接口的任意实现。