從零構建一個pile(`/books/(?Pd+)/(?Pd+)`,)match:=r.FindStringSubmatch("/books/123/456")ifmatch==nil{return}fmt.Println(match)//[123,456]fmt.Println(r.SubexpNames())//[AuthorID,BookID]保存網址參數知道如何匹配正則表達式組,我們將可以更新RouteEntry結構的匹配邏輯以使用它們。為此,需要將Path屬性從字符串更改為Regexp類型。然后,需要更新Match方法邏輯。typeRouteEntrystruct{Path*regexp.RegexpMethodstringHandlerFunchttp.HandlerFunc}func(ent*RouteEntry)Match(r*http.Request)map[string]string{match:=ent.Path.FindStringSubmatch(r.URL.Path)ifmatch==nil{returnnil}params:=make(map[string]string)groupNames:=ent.Path.SubexpNames()fori,group:=rangematch{params[groupNames[i]]=group}returnparams}注意,上面還更改了的簽名Match以返回參數映射,而非布爾值。最后需要做的一件事是更新路由器邏輯,以在找到匹配項后將參數添加到請求上下文中。for_,e:=rangertr.routes{params:=e.Match(r)ifparams==nil{continue}ctx:=context.WithValue(r.Context(),"params",params)e.HandlerFunc.ServeHTTP(w,r.WithContext(ctx))return}我們在程序中添加這些部分,然后測試:Panic恢復添加動態URL參數極大地提高了路由器的實用性。現在可以將其在一些項目中使用。為了防止生產中發生壞事,應該增加另外一件事,那就是緊急恢復。當前,如果路由處理程序之一出現緊急情況,服務器將返回一個空響應,而不是默認頁面。將添加以下幾行代碼來捕獲這些緊急情況并返回適當的500(內部服務器錯誤)狀態代碼。func(rtr*Router)ServeHTTP(whttp.ResponseWriter,r*http.Request){deferfunc(){ifr:=recover();r!=nil{log.Println("ERROR:",r)http.Error(w,"發生錯誤…",http.StatusInternalServerError)}}()//...}為了測試它是否有效,我們添加一條特殊的/panic路由來觸發該恢復邏輯。r.Route("GET",r*http.Request){panic("somethingbadhappened!")})測試訪問127.0.0.1:8000/panic,就會返回Uhoh!總結本我們實例介紹了如何使用Golang語言的標準庫,從頭開始構建一個路由器,當然我們構建的路由器僅僅為HTTP路由原理說明、練手和好玩,不建議在生產環境使用!在生產中使用建議使用成熟的類庫,比如gorilla/mux。