我正在编写一个包含从 XML-RPC 服务器读取数据并将其存储在 go 结构数组中的函数的包。这是两种结构的片段:http ://play.golang.org/p/a1dVA0UCzS 。对于每种类型的结构,我都有一个单独的“转换”功能。总共有 20 多个 - 只是彼此的普通副本,只是替换了结构名称。
是否有一个优雅的解决方案,而不是愚蠢的复制/粘贴相同的代码?
您可以通过使用反射来做到这一点。请参阅pkg/reflect
文档。
你的情况reflect.MakeFunc
很有趣。您可以使用反射创建函数,然后发送消息并知道它们将接收的类型。示例用法:
var getFooRequest func() []Foo // Prototype of request.
buildRequest("FooStore.GetFoo", &getFooRequest) // Build request function.
result := getFooRequest() // Actually sending.
一个工作示例(play):
func makeRequestFunc(req string, fptr interface{}) {
baseRequestFunc := func(params []reflect.Value) []reflect.Value {
log.Println("Sending", req)
return []reflect.Value{ reflect.ValueOf([]int{1,2,3,4}) }
}
fn := reflect.ValueOf(fptr).Elem()
reqFun := reflect.MakeFunc(fn.Type(), baseRequestFunc)
fn.Set(reqFun)
}
var fooRequest func() []int
makeRequestFunc("foo", &fooRequest)
log.Println( fooRequest() )
baseRequestFunc
store.client.Call
在这个例子中,你可以用你喜欢的任何字符串调用你的地方。从这个基本函数中,您可以创建一个可调用的新函数,reflect.MakeFunc
并将结果存储在传递的函数指针中。
由于fooRequest
具有明确的签名,因此不需要解包值。