为了账号安全,请及时绑定邮箱和手机立即绑定

我正在编写一个具有 irc 样式命令的聊天应用程序。构建程序以处理这些命令的最佳方法是什么?

我正在编写一个具有 irc 样式命令的聊天应用程序。构建程序以处理这些命令的最佳方法是什么?

Go
慕桂英3389331 2021-09-27 17:42:52
我正在编写本质上是一个聊天程序。我想在其中包含一些特殊的 irc 样式命令,但我似乎无法概念化如何构建程序。我想知道人们是否可以从高层次的角度帮助我。我不是在寻找代码,只是关于如何最好地进行的想法。我最好的尝试是有一个像下面这样的命令结构:type Command struct {  name     string // the name of the command  function string // the function that will be called upon match  help     string // the help message for the command  regex    string // the regex pattern that will run the command}然后有一个命令片段,每次我收到来自客户端的消息时就迭代它。如果接收到的数据与正则表达式匹配,那么反射(我认为这会起作用)包调用“函数”。出于某种原因,我觉得必须有更好的方法。我正在学习自己编写 Go 代码,并且没有可用的资源来激发灵感。我非常感谢您对此的想法。
查看完整描述

2 回答

?
largeQ

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 语言规范中的函数类型和函数文字。


查看完整回答
反对 回复 2021-09-27
?
德玛西亚99

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)}}

它不必具有完全相同的签名。您可以让它接受连接或其他任何东西。您也不必内联函数定义,您可以引用任何您想要的具有适当签名的函数。


查看完整回答
反对 回复 2021-09-27
  • 2 回答
  • 0 关注
  • 218 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信