写这篇文章的初衷是因为最近被GoLang的一个低级问题搞蒙了,加上本蠢货用的还是IntelliJ的2017版本,对GoLang的错误提示非常有限,导致为了解决一个回调问题花了一个多小时。
问题呢,就是GoLang的回调了,在我的印象中GoLang实现回调和Java有那么一点区别,但是大同小异。首先如果是个简单的回调那么肯定没啥难度,传入一个struct对象就可以了,但是我想的是可以随时创建这个回调对象,在各种场合,那么就决定了这个回调对象可能是多个,所以必须是接口。
so,思路其实很清晰,回调参数使用接口就可以了,但是今天我被自己蠢到了,忘了GoLang的特性,首字母非大写是不能给外部包调用的,所以,一言难尽。
在解决问题的期间我不服气的搜了百度与google,发现搜出来的内容居然都是传入func对象来实现回调,这简直太low了,因为回调可能有多个方法,每个方法传一个对象进来吗?
所以,我觉得有义务写这篇文章,给GoLang的回调添加一个形式,那么来贴代码吧。
fileserver包:文件服务,用于文件查询与提供下载服务。
type StartCallBack interface {
OnError(err error)
OnSuccess(files []*entity.File)
}
func StartFile(conf *entity.FileServerConf, startCallBack StartCallBack) {
// 获取文件的MD5
files, err := queryFileList(conf.FilePath)
if err != nil {
log.Println("queryFileList err:", err.Error())
startCallBack.OnError(err)
return
}
log.Println("startCallBack:", startCallBack)
// 回调通知文件查询成功,后面服务开启
startCallBack.OnSuccess(files)
// 开启文件服务
...
}
main包:调用打开文件服务
type StartCallBackTest struct {
//fileserver.StartCallBack
}
func (scbt StartCallBackTest) OnError(err error) {
log.Println("error:", err.Error())
}
func (scbt StartCallBackTest) OnSuccess(files []*entity.File) {
log.Println("on success:", len(files))
}
func main() {
conf := &entity.FileServerConf{
Port: "8081",
Route: "/staticfile/",
FilePath: "./staticfile",
}
startCallBacktest := StartCallBackTest{}
log.Println("startCallBacktest:", startCallBacktest)
fileserver.StartFile(conf, startCallBacktest)
}
从代码中可以看到这是用接口来实现的回调,使用中需要注意,在StartFile方法中接口参数不能使用指针类型,因为需要GoLang做识别是否是这个接口实现。OnError方法前面的所属定义也不能是指针类型。
OK,以后回调就用接口吧,爽太多了。