英文:
GO: find/scan for structs/functions
问题
在Go语言中,可以通过名称、标签或接口等条件来查找结构体或函数吗?例如类似于命令行任务/动词的方式?
func cmd1() {
...
}
func cmd2() {
...
}
...
func cmdN() {
}
func main() {
// 检查 os.Args 并根据参数调用 cmd{X}() 函数。
...
}
我不介意具体的机制,也不介意最终的目标是函数还是结构体——目标是通过约定而不需要任何样板代码来实现某种工作方式。
英文:
Is it possible in GO to find structs or functions by criteria such as name, tag or interface? i.e something along the lines of command line tasks/verbs? i.e:
func cmd1() {
...
}
func cmd2() {
...
}
...
func cmdN() {
}
func main() {
// Inspect os.Args and call cmd{X}() based on args.
...
}
I don't mind what the exact mechanism is and if the final targets are functions or structs - the goal is to get something working by convention without any boilerplate code.
答案1
得分: 1
你可以使用反射或者使用映射来实现。
使用反射的代码如下:
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 + " 不是一个有效的命令")
return
}
cmd.Call([]reflect.Value{})
}
func (c command) Cmd1() {
fmt.Println("命令 1")
}
func (c command) Cmd2() {
fmt.Println("命令 2")
}
func (c command) Cmd3() {
fmt.Println("命令 3")
}
func main() {
flag.Parse()
cmd.execute(flag.Arg(0))
}
或者你可以使用映射的方式实现:
package main
import (
"flag"
"fmt"
)
func cmd1() {
fmt.Println("命令 1")
}
func cmd2() {
fmt.Println("命令 2")
}
func cmd3() {
fmt.Println("命令 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) + " 命令未找到")
}
}
希望对你有帮助!
英文:
You could use reflection
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))
}
or you could use a map.
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")
}
}
答案2
得分: 0
我在《如何在Go中使用反射测试函数集合?》中使用了类似的方法。
思路是列出并找到所有所需的函数,对于我的情况来说,是某个结构体类型的函数:
stype := reflect.ValueOf(s)
for _, fname := range funcNames {
sfunc := stype.MethodByName(fname)
// 无参数 => 空的 Value 切片
ret := sfunc.Call([]reflect.Value{})
}
英文:
I used a similar approach in "How to test a collection of functions by reflection in Go?"
The idea is to list and find all the functions needed, in my case, functions for a certain struct type:
stype := reflect.ValueOf(s)
for _, fname := range funcNames {
sfunc := stype.MethodByName(fname)
// no parameter => empty slice of Value
ret := sfunc.Call([]reflect.Value{})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论