由于剛剛接觸golang,對語言和用法都不太熟,看到這種寫法感覺很奇怪:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
我內(nèi)心就覺得為啥要這么多此一舉呢?把一個func定義為一個類型,然后實現(xiàn)ServeHTTP函數(shù)。為啥不直接用那個函數(shù)呢?
來看看http.ListenAndServe()接口的原型就明白了:
func ListenAndServe(addr string, handler Handler) error
函數(shù)的第二個參數(shù)是一個Handler interface,也就是說要使用這個函數(shù)那么需要傳入一個實現(xiàn)了ServerHTTP函數(shù)的類型。
對于復(fù)雜的應(yīng)用來說可能會專門定義一個struct來實現(xiàn)http.Handler接口,那么就傳入這個struct的事例進去就行了。但是如果簡單的應(yīng)用也這么做就有點劃不來了,因此http包提供了HandlerFunc類型來輔助用戶將一個函數(shù)快速轉(zhuǎn)換為符合http.Handler接口的類型。這種方法叫adapter function type[1]。
這種技巧的關(guān)鍵就是將符合接口的函數(shù)定義為類型,然后對這個類型實現(xiàn)接口中的函數(shù),實現(xiàn)的時候就直接調(diào)用自身。使用的時候只需要將自定義的函數(shù)(原型相同)做類型轉(zhuǎn)換就完成了。
實際上不光是標(biāo)準(zhǔn)庫用到這樣的技巧,在很多golang初學(xué)者都會看的groupcache中也用到了[2]。
參考
[1] https://github.com/gopherchina/conference/blob/master/2017/1.3%20Go%20coding%20in%20go%20way.pdf
[2] https://github.com/golang/groupcache/blob/master/groupcache.go