。 Value.Interface()
メソッドを使用して、reflect.Value
で表される値をinterface{}
値にすることができます。そこから、type assertionを使用してさまざまなタイプの値を取得できます。この単純な例では
同様:
var funcList = map[string]interface{}{
"test": func(ctx context.Context, data interface{}) (interface{}, error) {
return "test-result-data:" + fmt.Sprint(data), errors.New("test-error")
},
}
func Send(funcName string, data interface{}) (interface{}, error) {
f := reflect.ValueOf(funcList[funcName])
params := []reflect.Value{
reflect.ValueOf(context.Background()),
reflect.ValueOf(data),
}
res := f.Call(params)
ret := res[0].Interface()
var err error
if v := res[1].Interface(); v != nil {
err = v.(error)
}
return ret, err
}
テストそれ:
result, err := Send("test", "testData")
fmt.Println(result, err)
出力:
test-result-data:testData test-error
しかし、これは不必要に複雑です。あなたはこのように、あなたはそれを直接呼び出し、直接結果を返すことがあり、機能を呼び出すためにリフレクションを使用する必要はありません。
func Send2(funcName string, data interface{}) (interface{}, error) {
return funcList[funcName].(func(context.Context, interface{}) (interface{}, error))(
context.Background(), data,
)
}
テストそれ:
result, err = Send2("test", "testData")
fmt.Println(result, err)
出力が同じです。 Go Playgroundの例を試してみてください。
あなたはそれらを手に入れています。あなたのコードの 'value'は戻り値のスライスになります。あなたは何を持っているのですか? – Adrian
['Call'署名](https://golang.org/pkg/reflect/#Value.Call)を見ると、あなたの' value'は '[] reflect.Value'です。あなたはこれを印刷します。何が問題なのですか? – JimB
ちょうど不思議なことに、なぜ反射を使用するのですか。なぜそれを直接呼び出すのではなく、結果を返しますか? (インタフェース{}、エラー))(ctx、data) '?funcList [funcName.String()](func(context.Context、interface {})) (タイプアサーションは、異なるタイプの関数が 'funcList'に格納されている場合にのみ必要です;そうでなければ、それを取り除くことができ、' funcList [funcName.String()](ctx、data) 'を返します。 – icza