Go语言 接口型函数

从net/http聊起

使用net/http构建简单的http服务时候,我们经常是调用http.HandleFunc。但是还有http.Handle函数。看看其是如何使用的。

// 只写函数
func myFunc(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte(r.URL.Path))
}

// 需要写结构体
type httpServer struct {
}

func (server httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte(r.URL.Path))
}

func main() {
	//http.HandlerFunc(myFunc)不是调用函数,而是进行类型强制转换
	http.Handle("/func", http.HandlerFunc(myFunc))

	var server httpServer
	http.Handle("/handler", server)

	http.HandleFunc("/HandleFunc", myFunc)

	http.ListenAndServe("localhost:10000", nil)
}

http.Handle函数原型是func Handle(pattern string, handler Handler)

这里会不会很好奇http.Handle的第二个参数,可以传入函数,也可以传入结构体变量

接口型函数

查看net/http源码:

//接口
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(ResponseWriter, *Request),接着定义了一个函数类型 HandlerFuncHandlerFunc参数和返回值与 Handler中的ServeHTTP方法是一致的。

而且 HandlerFunc还定义了ServeHTTP方式,并在 ServeHTTP方法中调用自己,这样就实现了接口 Handler。

所以 HandlerFunc是一个实现了接口的函数类型,简称为接口型函数

从HandlerFunc类型中可知,函数myFunc的参数和返回值都与HandlerFunc是一致的,所以可以进行类型强制转换。

用接口型函数的好处

从前面的例子来说,使用接口型函数可以减少代码量,可读性也不错。

  • 使用接口型函数入参的话,只需要写一个函数即可(也可使用匿名函数);
  • 而使用结构体的话,就需要声明新的类型(如结构体httpServer),接着再实现该接口内的方法(ServeHTTP)。使用时候就还需要创建出该结构体变量,把该结构体变量传入。

总结

接口型函数就是该函数类型实现了这个接口。(例子参考net/http的HandlerFunc)

函数类型实现了接口,那函数参数是接口的时候,既能够将普通的函数类型(需类型转换)作为参数,也可以将结构体作为参数,使用更为灵活,可读性也更好,这就是接口型函数的价值。

你可能感兴趣的:(golang,开发语言,后端)