如何在golang中优雅地动态调用方法而不使用反射?

And*_*row 1 reflection pointers function-pointers go

我正在使用反射来执行此操作:

        method_name := CommandMap[command]
    thing := reflect.ValueOf(self).MethodByName(method_name)
    thing_s := fmt.Sprintf("%s", thing)
    if thing_s == "<invalid reflect.Value>" {
        self.writeMessage(550, "not allowed")
    } else {
        thing.Call([]reflect.Value{})
    }
Run Code Online (Sandbox Code Playgroud)

但一定有更好的方法。上面代码的目的是摆脱:

if command == "this" {
  runThis()
} else if command == "that" {
  runThat()
} etc. etc.
Run Code Online (Sandbox Code Playgroud)

我不想有一棵大的 if else 树。这是一个 ftp 服务器http://github.com/andrewarrow/paradise_ftp,我需要处理 15 个左右的命令,如“USER”、“PASS”和“QUIT”等。我希望每个命令都调用一个方法,如“handleUser”或“handlePass”。但使用反射是一个坏主意。太慢了。

小智 7

从链接的用例来看,拥有字符串到函数的映射似乎效果最好。例子:

func MakeCommandMap() map[string]func(*Paradise) {
    m := map[string]func(*Paradise){
        "USER": (*Paradise).HandleUser,
        "PASS": (*Paradise).HandlePass,
    }
    // ...
    return m
}
Run Code Online (Sandbox Code Playgroud)

调用函数:

name := "USER"
if fn := m[name]; fn != nil {
    fn(self) // where self is *Paradise
}
Run Code Online (Sandbox Code Playgroud)