Go語言是一個神奇的語言,尤其是函數(shù)式編程,
專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站制作服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)二道免費做網(wǎng)站提供優(yōu)質(zhì)的服務。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了1000多家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
就是一個典型。這個函數(shù)就是注冊默認路由。
HandleFunc 的第一個參數(shù)指的是請求路徑,第二個參數(shù)是一個函數(shù)類型,表示這個請求需要處理的事情。沒有處理復雜的邏輯,而是直接給DefaultServeMux處理,如源碼:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
DefaultServeMux 是ServeMux一個全局實例,
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
這個實例在被申明的時候初始化了,只要使用了DefaultServeMux這個變量,其實就是同一個指針而已,也就是獨一份。
DefaultServeMux.HandleFunc(pattern, handler) 函數(shù)其實也沒有做什么,直接調(diào)用路由注冊:
// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
mux.Handle(pattern, HandlerFunc(handler))
}
把自定義處理業(yè)務的函數(shù)進行路由注冊,HandlerFunc(handler) 這個處理其實是類型轉(zhuǎn)化,把函數(shù)handler func 類型轉(zhuǎn)化成HandlerFunc類型,是一個強制轉(zhuǎn)化,只要函數(shù)的參數(shù)類型一致,即可轉(zhuǎn)化。我們來看一個HandlerFunc是如何定義的:
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
從type可以看出 HandlerFunc 就是一個自定義類型,被定義成
func(ResponseWriter, *Request)
函數(shù)。所以只要符合此標準的函數(shù),都可以轉(zhuǎn)化成HandlerFunc,而這個函數(shù)實現(xiàn)了接口:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
這個接口就是路由中,匹配的處理方法。
根據(jù)go對接口的定義,只有實現(xiàn)了接口的所有方法,就實現(xiàn)了這個接口。
我們來看是如何注冊路由的,需要理解如下兩個結(jié)構(gòu)
type ServeMux struct {
mu sync.RWMutex //鎖
m map[string]muxEntry //路由集合
hosts bool // whether any patterns contain hostnames
}
type muxEntry struct {
explicit bool //是否已經(jīng)存在
h Handler //路由處理邏輯 是一個接口實例 在每次匹配的時候,調(diào)用此接口的方法
pattern string//請求路徑
}
處邏輯源碼如下:
// Handle 根據(jù)給定的請求路勁進行注冊路由
// 如果Handle已經(jīng)存在,就直接報錯
func (mux *ServeMux) Handle(pattern string, handler Handler) {
//進行加鎖,高并發(fā)處理
mux.mu.Lock()
//釋放鎖
defer mux.mu.Unlock()
//請求路徑為空,直接報錯
if pattern == "" {
panic("http: invalid pattern " + pattern)
}
//Handle不存在,直接報錯
if handler == nil {
panic("http: nil handler")
}
//如果Handle已經(jīng)存在,就直接報錯
if mux.m[pattern].explicit {
panic("http: multiple registrations for " + pattern)
}
//路由表不存在,創(chuàng)建一個,這個路由表是一個映射MAP
//key 就是請求路徑 value是muxEntry 包含具體路由信息
if mux.m == nil {
mux.m = make(map[string]muxEntry)
}
mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern}
//如果首字母不是‘/’ 包含hostName
if pattern[0] != '/' {
mux.hosts = true
}
// Helpful behavior:
// If pattern is /tree/, insert an implicit permanent redirect for /tree.
// It can be overridden by an explicit registration.
n := len(pattern)
//如何是像/tree/ 請求注冊路由,而且/tree 還沒有注冊過
if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {
// If pattern contains a host name, strip it and use remaining
// path for redirect.
path := pattern //保存原始路徑
if pattern[0] != '/' { //如果首字母不是 ‘/’
// In pattern, at least the last character is a '/', so
// strings.Index can't be -1.
path = pattern[strings.Index(pattern, "/"):] //返回最近的/之后的串作為請求路徑
}
//構(gòu)建請求URL 直接重定向 而且注冊的注冊路徑有/tree/ /tree
url := &url.URL{Path: path}
mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(url.String(), StatusMovedPermanently), pattern: pattern}
}
}
以上是對函數(shù)
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
調(diào)用過程分析
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
網(wǎng)站題目:http.HandleFunc解析-創(chuàng)新互聯(lián)
鏈接URL:http://bm7419.com/article42/dihghc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供服務器托管、域名注冊、網(wǎng)站收錄、網(wǎng)站策劃、云服務器、移動網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容