Go 事件驱动 实现事件的晌应和处理

在C语言里面也有 很多这样的代码 这里go版本

基本观点:

Go语言可以将类型的方法与普通函数视为一个概念,

从而简化方法和函数混合作为回调类型时的复杂性。

这个特性和 C# 中的代理(delegate)类似,

调用者无须关心谁来支持调用,系统会自动处理是否调用普通函数或类型的方法。

测试代码:

package main

import "fmt"

// 声明一个结构体
type class struct {
}

// 给结构体添加Do方法
func (c *class) Do(v int) {
	fmt.Println("call method do:", v)
}

// 普通函数的Do
func funcDo(v int) {
	fmt.Println("call function do:", v)
}

func main() {
	// 声明一个函数回调
	var delegate func(int)
	// 创建结构体实例
	c := new(class)
	// 将回调设为c的Do方法
	delegate = c.Do
	// 调用
	delegate(100)

	// 将回调设为普通函数
	delegate = funcDo
	// 调用
	delegate(100)
}

结果:

[Running] go run "c:\Users\Koson.Gong\Desktop\sgo\main.go"

call method do: 100

call function do: 100

例子是让一个结构体的方法(class.Do)的参数和一个普通函数(funcDo)的参数完全一致。

然后使用与它们签名一致的函数变量(delegate)分别赋值方法与函数,

接着调用它们,观察实际效果。

代码说明如下:

  • 第 10 行,为结构体添加一个 Do() 方法,参数为整型。
  • 第 16 行,声明一个普通函数,参数也是整型。
  • 第 24 行,声明一个 delegate 的变量,类型为 func(int),与 funcDo 和 class 的 Do() 方法的参数一致。
  • 第 30 行,将 c.Do 作为值赋给 delegate 变量。
  • 第 33 行,调用 delegate() 函数,传入 100 的参数。此时会调用 c 实例的 Do() 方法。
  • 第 36 行,将 funcDo 赋值给 delegate。
  • 第 39 行,调用 delegate(),传入 100 的参数。此时会调用 funcDo() 方法。

运行代码,输出如下:

call method do: 100
call function do: 100

这段代码能运行的基础在于:无论是普通函数还是结构体的方法,只要它们的签名一致,与它们签名一致的函数变量就可以保存普通函数或是结构体方法。了解了 Go语言的这一特性后,我们就可以将这个特性用在事件中。

Go语言事件系统实现事件的晌应和处理

package main

import "fmt"

// 声明角色的结构体
type Actor struct {
}

// 为角色添加一个事件处理函数
func (a *Actor) OnEvent(param interface{}) {

	fmt.Println("actor event:", param)
}

// 全局事件
func GlobalEvent(param interface{}) {

	fmt.Println("global event:", param)
}

func main() {

	// 实例化一个角色
	a := new(Actor)

	// 注册名为OnSkill的回调
	RegisterEvent("OnSkill", a.OnEvent)

	// 再次在OnSkill上注册全局事件
	RegisterEvent("OnSkill", GlobalEvent)

	// 调用事件,所有注册的同名函数都会被调用
	CallEvent("OnSkill", 100)

}
//

// 调用事件
func CallEvent(name string, param interface{}) {

	// 通过名字找到事件列表
	list := eventByName[name]

	// 遍历这个事件的所有回调
	for _, callback := range list {

		// 传入参数调用回调
		callback(param)
	}

}
///
// 实例化一个通过字符串映射函数切片的map
var eventByName = make(map[string][]func(interface{}))

// 注册事件,提供事件名和回调函数
func RegisterEvent(name string, callback func(interface{})) {

	// 通过名字查找事件列表
	list := eventByName[name]

	// 在列表切片中添加函数
	list = append(list, callback)

	// 将修改的事件列表切片保存回去
	eventByName[name] = list
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值