2 回答
TA贡献2039条经验 获得超7个赞
在 IRC 风格的命令中,命令行通常如下所示:
/cmd [param1] [param2] ... [paramn]
当收到这样的命令时,您可以使用拆分它strings.Split()来获取命令的部分或令牌。这样,您将拥有识别命令的第一个标记。
您可以构建一个map[string]Command映射,将文本命令映射到它们的Command结构。在这张地图中,您可以通过简单地索引地图来获取命令,例如:
cmdMap := make(map[string]Command)
// Populate map
textCmd := "/help"
cmd := cmdMap[textCmd]
如果你想有命令别名(例如,你想/help和/h和/?所有做相同的),您可以存储别名每个命令的列表,当你建立cmdMap,也为所有的别名,以点条目添加到相同的Command结构,在这种情况下,您应该像这样定义它:
cmdMap := make(map[string]*Command)
helpCmd := &Command{...} // Create help command
cmdMap["/help"] = helpCmd
cmdMap["/h"] = helpCmd
cmdMap["/?"] = helpCmd
注意:你也可以去掉领先斜线'/',只需使用该命令的其余部分("help","h"而"?"在这种情况下)来初始化您的地图,它给你。
此外,您不必存储函数的名称,Go 中的函数是值,因此您可以在Command结构中拥有一个函数字段,然后您无需反射即可调用该函数。例如:
func DoSomething() {
fmt.Println("Doing something...")
}
var someFv = DoSomething
// And now you can do:
someFv()
请参阅Go 语言规范中的函数类型和函数文字。
TA贡献1770条经验 获得超3个赞
首先,您不需要使用反射。您可以让Command结构包含具有 func 类型的成员。
type Command struct {
name string // the name of the command
f func(string) // the function that will be called upon match
help string // the help message for the command
regex regexp.Regexp // the regex pattern that will run the command
}
func processMessage(text string){
for _,cmd := range(allCmds){
if cmd.regex.MatchString(text){
cmd.f(text)
return
}
}
defaultAction(text) //or just add a catch-all with a regex of `.*`
}
然后您可以添加具有适当签名功能的命令:
cmd := Command{name: "foo",f: func(text string){fmt.Println(text)}}
它不必具有完全相同的签名。您可以让它接受连接或其他任何东西。您也不必内联函数定义,您可以引用任何您想要的具有适当签名的函数。
- 2 回答
- 0 关注
- 218 浏览
添加回答
举报