如何避免Go中的长switch case语句
我正在用Go写一个聊天机器人,想知道如何避免类似于下面这句的长切换案例声明:如何避免Go中的长switch case语句,go,Go,我正在用Go写一个聊天机器人,想知道如何避免类似于下面这句的长切换案例声明: switch { // @bot search me HMAC case strings.Contains(message, "search me"): query := strings.Split(message, "search me ")[1] return webSearch(query), "html" // @bot thesaurus me challenge case strings
switch {
// @bot search me HMAC
case strings.Contains(message, "search me"):
query := strings.Split(message, "search me ")[1]
return webSearch(query), "html"
// @bot thesaurus me challenge
case strings.Contains(message, "thesaurus me"):
query := strings.Split(message, "thesaurus me ")[1]
return synonyms(query), "html"
我应该在单独的包中分别定义这些处理程序,还是只使用结构和接口?哪种方法可以让我拥有一个好的结构,避免切换情况,让外部开发人员更容易地创建处理程序
我认为包是一个更好的选择,但我不确定如何向主bot注册处理程序。请举个例子。您可以使用类似于
net/http
包注册处理程序的map[string]命令。类似于此:
显然,这里缺少很多检查,但这是基本的想法。单独的包可能有些过分,但是如果您希望其他开发人员在不修改代码的情况下创建处理程序,switch语句将不起作用-它是用所有可用选项硬编码的。你想要一个映射之类的东西——以标准库的HTTP mux代码为例。长switch语句有什么问题?这就是switch的用途,@Volker对于其他开发人员来说它不是动态的。为什么不动态地生成switch语句呢case一些布尔值,使得消息位于dict的键列表中:在该dict中查找查询或执行任何操作,然后执行它;完成
。然后有一些函数,开发者可以在其中注册代码,从而将它们的处理程序或任何东西添加到groovy dict中。我希望每个处理程序都有一个用于匹配的正则表达式,一个用于帮助的描述/用法,以及一个要执行的函数。无法想出一个不需要重复的方法,例如在Handler struct和switch case中都使用“search me”来执行正确的函数。谢谢,这很有帮助。然而,我不确定我是否理解如何使用正则表达式来实现这一点。我使用命名捕获来获取用户的输入。有什么想法吗?这是一个独立的问题,完全取决于你如何定义你的命令结构。如果你还没有,坐下来试着完全定义一个命令是如何构造的,这将帮助你确定如何解析它。它们实际上是两个独立的问题。换一种说法。这里的礼仪要求每个帖子应该有一个问题。考虑到您对regex的关注范围不同,这确实是一个不同的问题。另外,我在答案中添加了一些修饰语。@Maklaus plus,解析命令和查询所需的答案不仅限于Go,它是一个更广泛的问题。它将受益于在自己的问题中使用不同的标签来定位正确的受众。用“go
标记某事物”可能更能减少看到问题的人的数量。。。
package main
import (
"fmt"
"errors"
)
type BotFunc func(string) (string, error)
type BotMap map[string]BotFunc
var Bot = BotMap{}
func (b BotMap) RegisterCommand(command string, f BotFunc) error {
if _, exists := b[command]; exists {
return errors.New("command already exists")
}
b[command] = f
return nil
}
func (b BotMap) Execute(statement string) (string, error) {
// parse out command and query however you choose (not this way obviously)
command := statement[:9]
query := statement[10:]
return b.ExecuteQuery(command, query)
}
func (b BotMap) ExecuteQuery(command, query string) (string, error) {
if com, exists := b[command]; exists {
return com(query)
}
return "", errors.New("command doesn't exist")
}
func main() {
err := Bot.RegisterCommand("search me", func(query string) (string, error) {
fmt.Println("search", query)
return "searched", nil
})
if err != nil {
fmt.Println(err)
return
}
err = Bot.RegisterCommand("thesaurus me", func(query string) (string, error) {
fmt.Println("thesaurus", query)
return "thesaurused", nil
})
if err != nil {
fmt.Println(err)
return
}
result, err := Bot.Execute("search me please")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
}