由于剛剛接觸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)心就覺得為啥要這么多此一舉呢?把一個(gè)func
定義為一個(gè)類型,然后實(shí)現(xiàn)ServeHTTP
函數(shù)嚼蚀。為啥不直接用那個(gè)函數(shù)呢?
來看看http.ListenAndServe()接口的原型就明白了:
func ListenAndServe(addr string, handler Handler) error
函數(shù)的第二個(gè)參數(shù)是一個(gè)Handler interface
管挟,也就是說要使用這個(gè)函數(shù)那么需要傳入一個(gè)實(shí)現(xiàn)了ServerHTTP
函數(shù)的類型轿曙。
對于復(fù)雜的應(yīng)用來說可能會專門定義一個(gè)struct
來實(shí)現(xiàn)http.Handler
接口,那么就傳入這個(gè)struct
的事例進(jìn)去就行了僻孝。但是如果簡單的應(yīng)用也這么做就有點(diǎn)劃不來了拳芙,因此http
包提供了HandlerFunc
類型來輔助用戶將一個(gè)函數(shù)快速轉(zhuǎn)換為符合http.Handler
接口的類型。這種方法叫adapter function type
[1]
皮璧。
這種技巧的關(guān)鍵就是將符合接口的函數(shù)定義為類型,然后對這個(gè)類型實(shí)現(xiàn)接口中的函數(shù)分飞,實(shí)現(xiàn)的時(shí)候就直接調(diào)用自身悴务。使用的時(shí)候只需要將自定義的函數(shù)(原型相同)做類型轉(zhuǎn)換就完成了。
實(shí)際上不光是標(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