什么是回调函数? 在维基百科中,给出了这么一个定义:在计算机程序设计中,回调函数,或简称回调(Callback 即call then back 被主函数调用运算后会返回主函数),是指通过参数将函数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。
从图中可以这么理解,主程序在调用软件库的时候同时传入了一个回调函数,用来告诉这个库函数在执行完成后需要回调的函数,也就是主函数在调用库函数的同时也指定了回调函数,这样整个程序的灵活性会大大增强,通过传入不同的回调函数,就可以实现各种不同的功能。
在device-sdk-go中,以restrouter.go举例,在添加路由的时候,设置了如下的回调函数:
1 2 3 4 5 6 7 8 c.addReservedRoute(common.ApiDeviceCallbackRoute, c.AddDevice).Methods(http.MethodPost) c.addReservedRoute(common.ApiDeviceCallbackRoute, c.UpdateDevice).Methods(http.MethodPut) c.addReservedRoute(common.ApiDeviceCallbackNameRoute, c.DeleteDevice).Methods(http.MethodDelete) c.addReservedRoute(common.ApiProfileCallbackRoute, c.UpdateProfile).Methods(http.MethodPut) c.addReservedRoute(common.ApiWatcherCallbackRoute, c.AddProvisionWatcher).Methods(http.MethodPost) c.addReservedRoute(common.ApiWatcherCallbackRoute, c.UpdateProvisionWatcher).Methods(http.MethodPut) c.addReservedRoute(common.ApiWatcherCallbackNameRoute, c.DeleteProvisionWatcher).Methods(http.MethodDelete) c.addReservedRoute(common.ApiServiceCallbackRoute, c.UpdateDeviceService).Methods(http.MethodPut)
先进入addReservedRoute()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 func (c *RestController) addReservedRoute(route string , handler func (http.ResponseWriter, *http.Request) ) *mux.Route { c.reservedRoutes[route] = true return c.router.HandleFunc(route, handler) } func (r *Router) HandleFunc(path string , f func (http.ResponseWriter, *http.Request) ) *Route { return r.NewRoute().Path(path).HandlerFunc(f) } func (r *Route) Path(tpl string ) *Route { r.err = r.addRegexpMatcher(tpl, regexpTypePath) return r } func (r *Route) HandlerFunc(f func (http.ResponseWriter, *http.Request) ) *Route { return r.Handler(http.HandlerFunc(f)) }
这个意思就是设置route路径,并且设置了回调函数handler,比如设置的是c.AddDevice,那么回调函数就是AddDevice()方法,如果设置的是c.UpdateDevice,那么回调函数就是UpdateDevice()方法。继续看底层,
1 2 3 4 5 6 7 8 9 type Handler interface { ServeHTTP(ResponseWriter, *Request) } type HandlerFunc func (ResponseWriter, *Request) func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) }
由此可以看出Handler是一个接口,ServeHTTP是一个方法,而HandlerFunc通过实现ServeHTTP方法从而实现了Handler接口,它的类型就是外面传入的函数。