基于Go语言简单实现事件管理器

 更新时间:2023年11月27日 09:24:43   作者:洛天枫  
在编程中,事件管理器是一种常见的工具,用于通过通知来触发操作,本文将介绍一个简单的Go事件管理器的实现,并通过异步改进提高其性能,感兴趣的可以了解下

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

监听器

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

type Listener[T any] func(T)

事件管理器

事件管理器是一个用于管理事件和监听器的结构。它具有两个方法:AddRunAdd方法用于将新的监听器附加到事件上,而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语言的并发特性,提高事件处理效率。

到此这篇关于基于Go语言简单实现事件管理器的文章就介绍到这了,更多相关go事件管理器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang内存对齐详解

    golang内存对齐详解

    在golang中,每一种数据类型都有其对应的数据类型大小,也就是占用了多少内存空间,我们可以通过unsafe.Sizeof函数,来确定一个变量占用的内存字节数,本文将详细给大家介绍golang内存对齐,需要的朋友可以参考下
    2023-10-10
  • Go 1.21中引入的新包maps和cmp功能作用详解

    Go 1.21中引入的新包maps和cmp功能作用详解

    这篇文章主要为大家介绍了Go 1.21中引入的新包maps和cmp功能作用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Go语言 Channel通道详解

    Go语言 Channel通道详解

    Channel是一个通道,可以通过它读取和写入数据,它就像水管一样,网络数据通过Channel 读取和写入,这篇文章主要给大家介绍了关于Go语言 Channel通道的相关资料,需要的朋友可以参考下
    2023-07-07
  • GO语言实现TCP服务器的示例代码

    GO语言实现TCP服务器的示例代码

    这篇文章主要为大家详细介绍了如何通过GO语言实现TCP服务器,文中的示例代码讲解详细,对我们深入了解Go语言有一定的帮助,需要的可以参考一下
    2023-03-03
  • golang中判断请求是http还是https获取当前访问地址

    golang中判断请求是http还是https获取当前访问地址

    这篇文章主要为大家介绍了golang中判断请求是http还是https获取当前访问地址示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • GO必知必会的常见面试题汇总

    GO必知必会的常见面试题汇总

    这篇文章主要为大家介绍了GO必知必会的常见面试题汇总
    2022-08-08
  • Golang使用cobra实现命令行程序的示例代码

    Golang使用cobra实现命令行程序的示例代码

    Cobra 是 Go 语言中一个强大的命令行应用库,它提供了创建命令行工具所需的基本结构和功能,被许多开发者用于构建各种命令行工具和应用程序,本文将给大家介绍Golang使用cobra实现命令行程序,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2024-02-02
  • go语言的四数相加等于指定数算法

    go语言的四数相加等于指定数算法

    这篇文章主要介绍了go语言的四数相加等于指定数算法的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • golang踩坑实战之channel的正确使用方式

    golang踩坑实战之channel的正确使用方式

    Golang channel是Go语言中一个非常重要的特性,除了用来处理并发编程的任务中,它还可以用来进行消息传递和事件通知,这篇文章主要给大家介绍了关于golang踩坑实战之channel的正确使用方式,需要的朋友可以参考下
    2023-06-06
  • 详解Golang如何监听某个函数的开始执行和执行结束

    详解Golang如何监听某个函数的开始执行和执行结束

    这篇文章主要为大家详细介绍了Golang如何监听某个函数的开始执行和执行结束,文中的示例代码讲解详细,有需要的小伙伴可以参考一下
    2024-02-02

最新评论