@[TOC](go type func() 自定义函数类型)
因看不懂 go 中的自定义函数类型,看了https://www.jianshu.com/p/431abe0d2ed5 理解了不少,特此搬运到自己博客
在看golang 的http服务部分代码时,被golang 中的 type func()写法难住了,一时没看懂代码。后来查资料后,有了一点理解。
在golang中可以通过这样简单实现一个http服务
package main
import "net/http"
func mHttp ( ) {
http. HandleFunc ( "/" , h)
http. ListenAndServe ( "0.0.0.0:8888" , nil )
}
func h ( w http. ResponseWriter, r * http. Request) {
}
http.HandleFunc()
是一个注册函数,传一个string类型的路由,和一个函数,函数的参数为(http.ResponseWriter, *http.Request)。跟踪进入函数,在golang 源码net/http/server.go文件中
func HandleFunc ( pattern string , handler func ( ResponseWriter, * Request) ) {
DefaultServeMux. HandleFunc ( pattern, handler)
}
在HandleFunc调用了DefaultServeMux.HandleFunc(pattern, handler)
至于这些函数是干啥的先不做探讨,这不是本文的重点。
再次跟进函数
func ( mux * ServeMux) HandleFunc ( pattern string , handler func ( ResponseWriter, * Request) ) {
if handler == nil {
panic ( "http: nil handler" )
}
mux. Handle ( pattern, HandlerFunc ( handler) )
}
在mux.Handle(pattern, HandlerFunc(handler)) 的第二个参数HandlerFunc(handler)是什么鬼。
跟进看一下
type HandlerFunc func ( ResponseWriter, * Request)
func ( f HandlerFunc) ServeHTTP ( w ResponseWriter, r * Request) {
f ( w, r)
}
原来HandlerFunc 是用 type 定义的函数,而函数的类型就是最开始传入的类型func(ResponseWriter, *Request)
ServeHTTP是HandlerFunc的一个方法(注意一下,golang中方法和函数不是一回事)。并且HandlerFunc实现了 Handler接口
Handler接口定义:
type Handler interface {
ServeHTTP ( ResponseWriter, * Request)
}
回到HandleFunc方法中,mux.Handle(pattern, HandlerFunc(handler))
的第二个参数是把传入的函数 handler 强转成 HandlerFunc类型,这样handler就实现了Handler接口。
到这我们明白HandlerFunc(handler)
是把普通函数强转成type定义的函数。
现在写一个简单的demo验证一下:
package main
import "fmt"
func main ( ) {
one ( 2 , callback)
}
func callback ( i int ) {
fmt. Println ( "i am callBack" )
fmt. Println ( i)
}
func one ( i int , f func ( int ) ) {
two ( i, fun ( f) )
}
func two ( i int , c Call) {
c. call ( i)
}
type fun func ( int )
func ( f fun) call ( i int ) {
f ( i)
}
type Call interface {
call ( int )
}
先看一下程序的运行结果:
我们在main()函数中调用了one()函数,并传入了callback()函数,最终调用了我们传入的callback()函数。
理一下思路:
使用type定义函数 func(int)
定义 Call 接口,Call中有一个函数 call(int)
在main()中调用one(2, callback),在one()中调用two(),传入two()函数前,对callback函数实现了类型转换,从普通函数转换成type定义的函数。
在 two() 中调用传入的 c 因为 c 实现了 Call 接口,所以可以调用 call() 函数,最终调用了我们传入的 callback() 函数。
请发表评论