Value.Call()
返回函數調用爲[]reflect.Value
的返回值。您可以使用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
想知道,爲什麼你使用反射,爲什麼不直接調用它,並返回結果,例如'funcName.String()]。(func(context.Context,interface {}))(interface {},error))(ctx,data)'' (只有在'funcList'中存儲不同類型的函數時才需要類型斷言;否則,您甚至可以擺脫它,並且它變爲'return funcList [funcName.String()](ctx,data)'。) – icza