在看golang 的http服務部分代碼時,被golang 中的 type func()寫法難住了,一時沒看懂代碼。后來查資料后,有了一點理解。
在golang中可以通過這樣簡單實現(xiàn)一個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()是一個注冊函數(shù),傳一個string類型的路由,和一個函數(shù),函數(shù)的參數(shù)為(http.ResponseWriter, *http.Request)。跟蹤進入函數(shù),在golang 源碼net/http/server.go文件中
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
在HandleFunc調(diào)用了DefaultServeMux.HandleFunc(pattern, handler)
至于這些函數(shù)是干啥的先不做探討,這不是本文的重點。
再次跟進函數(shù)
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)) 的第二個參數(shù)HandlerFunc(handler)是什么鬼。
跟進看一下
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
原來HandlerFunc 是用 type 定義的函數(shù),而函數(shù)的類型就是最開始傳入的類型func(ResponseWriter, *Request)
ServeHTTP是HandlerFunc的一個方法(注意一下,golang中方法和函數(shù)不是一回事)。并且HandlerFunc實現(xiàn)了 Handler接口
Handler接口定義:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
回到HandleFunc方法中,mux.Handle(pattern, HandlerFunc(handler))的第二個參數(shù)是把傳入的函數(shù) handler 強轉成 HandlerFunc類型,這樣handler就實現(xiàn)了Handler接口。
到這我們明白HandlerFunc(handler) 是把普通函數(shù)強轉成type定義的函數(shù)。
現(xiàn)在寫一個簡單的demo驗證一下:
package main
import "fmt"
func main() {
one(2, callback)
}
//需要傳遞函數(shù)
func callback(i int) {
fmt.Println("i am callBack")
fmt.Println(i)
}
//main中調(diào)用的函數(shù)
func one(i int, f func(int)) {
two(i, fun(f))
}
//one()中調(diào)用的函數(shù)
func two(i int, c Call) {
c.call(i)
}
//定義的type函數(shù)
type fun func(int)
//fun實現(xiàn)的Call接口的call()函數(shù)
func (f fun) call(i int) {
f(i)
}
//接口
type Call interface {
call(int)
}
先看一下程序的運行結果:

我們在main()函數(shù)中調(diào)用了one()函數(shù),并傳入了callback()函數(shù),最終調(diào)用了我們傳入的callback()函數(shù)。
理一下思路:
使用type定義函數(shù) func(int)
定義 Call 接口,Call中有一個函數(shù) call(int)
在main()中調(diào)用one(2, callback),在one()中調(diào)用two(),傳入two()函數(shù)前,對callback函數(shù)實現(xiàn)了類型轉換,從普通函數(shù)轉換成type定義的函數(shù)。
在 two() 中調(diào)用傳入的 c 因為 c 實現(xiàn)了 Call 接口,所以可以調(diào)用 call() 函數(shù),最終調(diào)用了我們傳入的 callback() 函數(shù)。