回调函数

什么是回调函数?

在维基百科中,给出了这么一个定义:在计算机程序设计中,回调函数,或简称回调(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)
}


// HandleFunc registers a new route with a matcher for the URL path.
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)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}

由此可以看出Handler是一个接口,ServeHTTP是一个方法,而HandlerFunc通过实现ServeHTTP方法从而实现了Handler接口,它的类型就是外面传入的函数。

作者

Cindy

发布于

2021-12-03

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×