闽公网安备 35020302035485号
type Listener[T any] func(T)事件管理器
type Manager[T any] interface {
Add(n string, l Listener[T])
Run()
}
抽象事件管理器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语言的并发特性,提高事件处理效率。