XML-RPC サーバーからデータを読み取り、それを go 構造体の配列に格納する関数を含むパッケージを作成しています。2 種類の構造体のスニペットを次に示します: http://play.golang.org/p/a1dVA0UCzS。構造体のタイプごとに、個別の「変換」関数があります。それらは全部で 20 以上あります - 構造体名だけが置き換えられた単純なコピーです。
同じコードの愚かなコピー/貼り付けの代わりに、エレガントなソリューションはありますか?
XML-RPC サーバーからデータを読み取り、それを go 構造体の配列に格納する関数を含むパッケージを作成しています。2 種類の構造体のスニペットを次に示します: 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
この例では、好きな文字列でyour を呼び出す場所です。この基本関数から、次を使用して呼び出し可能な新しい関数を作成reflect.MakeFunc
し、渡された関数ポインターに結果を格納します。
fooRequest
明確な署名があるため、値のアンパックは必要ありません。