GO:查找/扫描结构/函数

GO:查找/扫描结构/函数,go,Go,在GO中是否可以通过名称、标记或接口等条件查找结构或函数?i、 在命令行任务/动词行中添加一些东西?i、 e: func cmd1() { ... } func cmd2() { ... } ... func cmdN() { } func main() { // Inspect os.Args and call cmd{X}() based on args. ... } 我不介意确切的机制是什么,如果最终目标是函数或结构,那么目标就是让某些东西按照约定

在GO中是否可以通过名称、标记或接口等条件查找结构或函数?i、 在命令行任务/动词行中添加一些东西?i、 e:

func cmd1() {
    ...
}

func cmd2() {
    ...
}

...

func cmdN() {
}

func main() {
    // Inspect os.Args and call cmd{X}() based on args.
    ...
}

我不介意确切的机制是什么,如果最终目标是函数或结构,那么目标就是让某些东西按照约定工作,而不需要任何样板代码。

您可以使用反射

package main

import (
    "flag"
    "fmt"
    "reflect"
)

var cmd command

type command struct{}

func (c command) execute(name string) {
    v := reflect.ValueOf(c)

    cmd := v.MethodByName(name)
    if !cmd.IsValid() {
        fmt.Println(name + " not a command")
        return
    }

    cmd.Call([]reflect.Value{})
}

func (c command) Cmd1() {
    fmt.Println("command 1")
}

func (c command) Cmd2() {
    fmt.Println("command 2")
}

func (c command) Cmd3() {
    fmt.Println("command 3")
}

func main() {
    flag.Parse()

    cmd.execute(flag.Arg(0))
}
或者你可以用地图

package main

import (
    "flag"
    "fmt"
)

func cmd1() {
    fmt.Println("command 1")
}

func cmd2() {
    fmt.Println("command 2")
}

func cmd3() {
    fmt.Println("command 3")
}

var funcs = map[string]func(){
    "cmd1": cmd1,
    "cmd2": cmd2,
    "cmd3": cmd3,
}

func main() {
    flag.Parse()

    if f, ok := funcs[flag.Arg(0)]; ok {
        f()
    } else {
        fmt.Println(flag.Arg(0) + " command not found")
    }
}

我在“”中使用了类似的方法

其思想是列出并查找所需的所有函数,在我的例子中,是特定结构类型的函数:

stype := reflect.ValueOf(s)
for _, fname := range funcNames {
    sfunc := stype.MethodByName(fname)
    // no parameter => empty slice of Value
    ret := sfunc.Call([]reflect.Value{})

这让我想起,如果你将其转化为一个针对上述示例的最小答案,我会接受它。当然,但在我的例子中,这些函数有一个作为接收器的结构。其想法是获得一个按约定的习惯用法,而不必手动维护这样的列表,在我的特殊情况下,这将增加到约500项。不幸的是,这是唯一的方法。抱歉-刚刚意识到您的解决方案还需要事先了解方法。基本上这在围棋中是不可行的。。。