Go事件管理器:简单实现
创始人
2025-07-07 08:41:36
0

在编程中,事件管理器是一种常见的工具,用于通过通知来触发操作。在Go语言中,我们可以通过创建事件管理器和监听器来实现事件的处理。本文将介绍一个简单的Go事件管理器的实现,并通过异步改进提高其性能。

监听器

首先,我们需要创建一个监听器。在这个实现中,监听器只是一个接收事件参数的函数。

type Listener[T any] func(T)

事件管理器

事件管理器是一个用于管理事件和监听器的结构。它具有两个方法:Add和Run。Add方法用于将新的监听器附加到事件上,而Run方法用于执行事件管理器。

type Manager[T any] interface {
 Add(n string, l Listener[T])
 Run()
}

抽象事件管理器

为了方便使用,我们可以创建一个抽象事件管理器,它实现了事件管理器接口的一部分通用逻辑。虽然Go语言并不是面向对象的,但我们可以通过模拟来实现类似的效果。

type BaseManager[T any] struct {
 lst map[string][]Listener[T]
}

func (m *BaseManager[T]) Invoke(n string, args T) {
 for _, ls := range m.lst[n] {
  ls(args)
 }
}

func (m *BaseManager[T]) Add(n string, l Listener[T]) {
 m.lst[n] = append(m.lst[n], l)
}

BaseManager提供了Add方法用于添加监听器和Invoke方法用于触发指定事件的监听器。

具体事件管理器

下面是一个具体的事件管理器的示例实现:命令事件管理器。该管理器接收用户从控制台输入的命令,并根据命令类型触发相应的事件。

type Command struct {
 Kind string
 Args []string
}

type CommandEventManager struct {
 BaseManager[*Command]
}

func (m *CommandEventManager) Run() {
 var (
  inp  string
  args Command
 )

 fmt.Scanln(&inp)

 cmd := strings.Split(inp, ":")

 if l := len(cmd); l == 0 {
  m.Invoke("no-command", nil)
 } else if l > 1 {
  args.Args = strings.Split(cmd[1], " ")
 }

 args.Kind = cmd[0]

 m.Invoke("any-command", &args)
 m.Invoke(args.Kind, &args)
}

func NewCommandEventManager() Manager[*Command] {
 return &CommandEventManager{
  BaseManager: BaseManager[*Command]{lst: make(map[string][]Listener[*Command])},
 }
}

Run方法获取用户从控制台输入的命令,并解析命令参数。如果没有命令或者命令参数,则触发"no-command"事件;否则,触发"any-command"事件和具体命令的事件。

添加监听器

让我们向命令事件管理器添加一些监听器。

func main() {
 cem := NewCommandEventManager()

 cem.Add("no-command", func(_ *Command) {
  fmt.Println("no command was recieved")
 })

 cem.Add("any-command", func(c *Command) {
  fmt.Printf("the %s command was executed", c.Kind)
 })

 cem.Add("sum", func(c *Command) {
  a, _ := strconv.Atoi(c.Args[0])
  b, _ := strconv.Atoi(c.Args[1])
  fmt.Printf("the sum result is: %d", a+b)
 })

 cem.Run()
}

在上面的示例中,程序只执行一次,但你可以将其放在一个无限循环中以持续监听命令。

异步改进

可以将事件管理器的执行改为异步方式,以提高性能。每次执行事件时,可以将其作为一个goroutine进行处理。甚至可以将每个监听器的执行也放在一个goroutine中,以提高并发性能。

通过上述改进,我们可以更好地利用Go语言的并发特性,提高事件处理效率。

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...