go 函数转换成接口


写在前面

今天看cron源码的时候发现它支持Regist函数和接口,有一点思考。

上代码

// 定义了任务接口
type Job interface {
	Run()
}

// 定义了任务函数
type FuncJob func()

func (f FuncJob) Run() { f() }

它支持两种Regist方式

func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error) {
	return c.AddJob(spec, FuncJob(cmd))
}

func (c *Cron) AddJob(spec string, cmd Job) (EntryID, error) {
	schedule, err := c.parser.Parse(spec)
	if err != nil {
		return 0, err
	}
	return c.Schedule(schedule, cmd), nil
}

其中AddFunc是将cmd转换成了FuncJob类型,因为FuncJob也是一个func,并且函数签名是一样的,这样转没有问题。可是转换之后为什么能调用c.AddJob呢?AddJob的入参是Job接口类型。

关键在于下面这个函数

func (f FuncJob) Run() { f() }

在FuncJob上实现了Job interface,所以能这样转换。

一般很少在函数上定义函数,但是go是支持这样做的。这里这样做,将AddFunc和AddJob两个方法在底层实现了统一,可以学习一下。

源码位置:https://github.com/robfig/cron/blob/master/cron.go#L134


文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录