2 回答

TA貢獻1805條經(jīng)驗 獲得超10個贊
有兩種可能的方法。一種是通過反射,即reflect
封裝,特別是Call
方法。第二個是通過函數(shù)值和閉包。我不會推薦第一個解決方案,通常不鼓勵反射,因為它很復雜、容易出錯并且成本高昂。
通過反射解決方案(https://play.golang.org/p/3b5I77QMsFI):
type command struct {
name string
handler reflect.Value
args []reflect.Value
}
var table = map[string]command{
"Foo": {
name: "Foo",
handler: reflect.ValueOf(foo),
args: []reflect.Value{
reflect.ValueOf(1),
reflect.ValueOf("hello"),
},
},
"Bar": {
name: "Bar",
handler: reflect.ValueOf(bar),
args: []reflect.Value{
reflect.ValueOf(true),
reflect.ValueOf(5),
reflect.ValueOf("hello"),
},
},
}
func foo(f1 int, f2 string) {
fmt.Println("Foo:", f1, f2)
}
func bar(b1 bool, b2 int, b3 string) {
fmt.Println("Bar:", b1, b2, b3)
}
func main() {
for name, command := range table {
fmt.Println("Running", name)
command.handler.Call(command.args)
}
}
通過函數(shù)閉包解決方案(https://play.golang.org/p/8fM86lxalq1):
type MyFuncType func()
type command struct {
name string
handler MyFuncType
}
var table = map[string]command{
"Foo": {
name: "Foo",
handler: fooClosure(1, "hello"),
},
"Bar": {
name: "Bar",
handler: barClosure(true, 5, "hello"),
},
}
func foo(f1 int, f2 string) {
fmt.Println("Foo:", f1, f2)
}
func fooClosure(f1 int, f2 string) MyFuncType {
return func() {
foo(f1, f2)
}
}
func bar(b1 bool, b2 int, b3 string) {
fmt.Println("Bar:", b1, b2, b3)
}
func barClosure(b1 bool, b2 int, b3 string) MyFuncType {
return func() {
bar(b1, b2, b3)
}
}
func main() {
for name, command := range table {
fmt.Println("Running", name)
command.handler()
}

TA貢獻1866條經(jīng)驗 獲得超5個贊
對于那些在 2023 年及以后遇到這種情況的人...如果您出于測試目的而搜索此內容,或者您可以保證所有函數(shù)都具有相同的參數(shù)簽名,那么您可以大大簡化:
——注意!?。∵@并不能解決每個參數(shù)簽名不同的OP問題。然后你必須使用更像已接受的答案的東西。但由于這是“golang 中的函數(shù)調度映射”的最佳答案之一,我認為這會很有用
var dispatchMap = map[string]func(yourSignature type){
"Key": funcName,
"AnotherKey": anotherFunc,
}
例如...使用它來創(chuàng)建一個調度映射,以便在公共包裝器內進行表驅動測試,但測試是不同的,并且并不都使用相同的函數(shù)...
func Something(t *testing.T) {
value := "value"
assert.Equal(t, value, "value", "Didnt Pass???")
}
func FailSomething(t *testing.T) {
value := "nooo"
assert.Equal(t, value, "value", "Supposed to fail!")
}
var testMap = map[string]func(t *testing.T){
"TestSomething": Something,
"TestFailSomething": FailSomething,
}
func TestWrapper(t *testing.T) {
t.Parallel()
for name, testCommand := range testMap {
t.Run(name, testCommand)
}
}
- 2 回答
- 0 關注
- 194 瀏覽
添加回答
舉報