2013-12-21 11 views
5

リフレクションパッケージの.Call関数に関連する私のコードで最後に1つの問題がありました。適切に使用する方法。反射パッケージの通話、ゴラン?

だから私はこのようなコール作ってるんだ:

私はなく、かなり何
func (c *Controller) Root(params map[string][]string) map[string] string{} 

次のように私はには.callを作ってるんだ方法がある

params := "some map[string][]string" 
in := make([]reflect.Value,0) 
return_values := reflect.ValueOf(&controller_ref).MethodByName(action_name).Call(in) 

を私が必要とするマップを関数に適切に渡すために "in"変数を操作する方法を理解しています。 make()の2番目のパラメータはパラメータの長さですか?しかし、私はパラメータを適切に渡すために変数をどのようにフォーマットするのかをよく理解していません。再帰的にエラーメッセージが表示されます。

reflect: Call with too few input arguments 

ご協力いただければ幸いです。

答えて

4

Value.Call documentationから:

コールは、入力引数inを含む関数vを呼び出します。たとえば、len(in) == 3の場合、v.Call(in)は、Goコールv(in[0], in[1], in[2])を表します。

使用すると、1つのパラメータを持つ関数を呼び出すようにしたいのであれば、inは、あなたのケースmap[string][]stringには、 右のタイプの1 reflect.Valueが含まれている必要があります。

表現

in := make([]reflect.Value,0) 

はあなたとして受け取るパニック 必要性1つのパラメータではなく、ゼロになりますValue.Callにこれを渡す長さ0のスライスを作成します。

正しい呼び出しは次のようになります。私はあなたの最後の段落を理解していない

m := map[string][]string{"foo": []string{"bar"}} 

in := []reflect.Value{reflect.ValueOf(m)} 

myMethod.Call(in) 
+0

ああ、ありがとう、どうもありがとう! :)今日あなたのすべての助けを感謝します! – user1493543

6

コールは、1つのパラメータを必要とするコントローラにゼロパラメータを渡そうとしています(inは空のスライスです)。あなたはin := []reflect.Value{reflect.ValueOf(params)}のような何かをする必要があります。

あなたは方法を見つけた後、また、あなたは直接呼び出すことができますfunc取得するタイプのアサーションを使用し、その後、.Interface()を呼び出すことができます。

// get a reflect.Value for the method 
methodVal := reflect.ValueOf(&controller_ref).MethodByName(action_name) 
// turn that into an interface{} 
methodIface := methodVal.Interface() 
// turn that into a function that has the expected signature 
method := methodIface.(func(map[string][]string) map[string]string) 
// call the method directly 
res := method(params) 

(そして、あなたもキャッシュmethodは、キーマップ内でした。。メソッド名によって、あなたはreflect操作に次の呼び出しを行う必要はありませんしかし、あなたはそれを動作させるためにことを行う必要はありませんので)

+0

。 – nemo

+0

申し訳ありません。コードを追加しました。私は、あなたがメソッドを見つけたら 'interface {}'を取得し、残りを型アサーションで行います。 – twotwotwo

+0

(@ nemo - それは良いアイデアだとは思わないかもしれませんが?) – twotwotwo