国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - Golang中的路由使用詳解

Golang中的路由使用詳解

2020-05-16 15:08達聞西 Golang

這篇文章主要介紹了Golang中的路由使用詳解,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

之前有篇文章比較淺顯的分析了一下golang的服務器如何實現,還有Handler, DefaultServeMux,HandlerFunc的用處。

我們現在已經明白了DefaultServeMux就是存放patternhandler的地方,我們稱其為路由,那么我們可能會想,既然golang能夠實現這個路由,我們能否也模仿一個呢?

首先我們需要一個能夠保存客戶端的請求的一個容器(路由)。

創建路由結構體

?
1
2
3
type CopyRouter struct {
  router map[string]map[string]http.HandlerFunc
}

在這里我們創建了一個像DefaultServeMux的路由。

客戶端請求存入路由

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (c *CopyRouter) HandleFunc(method, pattern string, handle http.HandlerFunc) {
  if method == "" {
    panic("Method can not be null!")
  }
 
  if pattern == "" {
    panic("Pattern can not be null!")
  }
 
  if _, ok := c.router[method][pattern]; ok {
    panic("Pattern Exists!")
  }
 
  if c.router == nil {
    c.router = make(map[string]map[string]http.HandlerFunc)
  }
 
  if c.router[method] == nil {
    c.router[method] = make(map[string]http.HandlerFunc)
  }
  c.router[method][pattern] = handle
}

這里我們模仿源碼中的ServeMux將每一個URL所對應的handler保存起來。

實現Handler接口

?
1
2
3
4
5
func (c *CopyRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  if f, ok := c.router[r.Method][r.URL.String()]; ok {
    f.ServeHTTP(w, r)
  }
}

在這里為什么要實現這個Handler接口,因為我們發現在ListenAndServe方法中,最后會調用h.ServeHTTP(w, r),那么我們就只需要讓我們定義的路由實現Handler接口就可以了。

獲取一個路由

?
1
2
3
func NewRouter() *CopyRouter {
  return new(CopyRouter)
}

到這里,我們自己定義的路由就完成了,我們來看看使用方法。

?
1
2
3
4
5
6
7
8
9
func sayHi(w http.ResponseWriter, r *http.Request) {
  fmt.Fprint(w,"Hi")
}
 
func main() {
  copyRouter := copyrouter.NewRouter()
  copyRouter.HandleFunc("GET","/sayHi", sayHi)
  log.Fatal(http.ListenAndServe("localhost:8080", copyRouter))
}

這樣就完成了一個高仿版的自定義路由,是不是和golang提供給我們的ServeMux很像,當然我們這個路由是一個低配版的,還有很多細節沒有處理。

現在再看看,我們的main函數里面的代碼不是很美觀,每一次都要寫get或者post方法,那么我們能否提供一個比較美觀的方式呢?可以,那么我們再封裝一下。

?
1
2
3
4
5
6
7
8
9
func (c *CopyRouter) GET(pattern string, handler http.HandlerFunc){
  c.HandleFunc("GET", pattern, handler)
}
 
func (c *CopyRouter) POST(pattern string, handler http.HandlerFunc){
  c.HandleFunc("POST", pattern, handler)
}
 
...

然后再修改一下調用方式。

?
1
copyRouter.GET("/sayHi",sayHi)

現在看起來是不是就美觀很多了?是的,很多web框架也是這樣,為什么用起來就感覺很流暢,因為這些大神們就是站在我們開發者的角度來考慮問題,提供了很方便的一些用法,封裝的很完善。

再考慮一下,我們這個自定義的路由還能做些什么,如果我們要記錄每一次的訪問請求,該如何處理呢?也很簡單,我們只需要將邏輯寫在ServeHTTP方法中就可以了,稍微修改一下我們的代碼。

?
1
2
3
4
5
6
7
8
9
10
func (c *CopyRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  if f, ok := c.router[r.Method][r.URL.String()]; ok {
    func (handler http.Handler){
      start := time.Now()
      log.Printf(" 請求 [%s] 開始時間為 : %v\n", r.URL.String(), start)
      f.ServeHTTP(w, r)
      log.Printf(" 請求 [%s] 完成時間為 : %v\n", r.URL.String(), time.Since(start))
    }(f)
  }
}

這里我們又加入了一個記錄請求時間的功能,所以在這個自定義的路由里面還可以做更多的事情。

還有一點,就是我們在定義這個路由結構體的時候,能否將這個類型修改為Handler呢?也就是將這個類型map[string]map[string]http.HandlerFunc修改為map[string]map[string]http.Handler,是可以的,但是我們在調用的時候就需要在main方法里面做一下修改。

?
1
copyRouter.GET("/sayHi",HandlerFunc(sayHi))

在這里做一個強制轉換即可,但是這樣也不是很美觀。

看到這里,我們應該對一個源碼中的類型重點關注一下,那就是HandlerFunc。

?
1
2
3
4
5
type HandlerFunc func(ResponseWriter, *Request)
 
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
  f(w, r)
}

這里HandlerFunc起到了一個適配器的作用,這是一個非常巧妙的設計,不得不說golang在接口這方面確實設計的很精妙。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://segmentfault.com/a/1190000015324113

延伸 · 閱讀

精彩推薦
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 久久久久国产精品免费免费搜索 | 精品一区二区电影 | 永久黄网站色视频免费 | 国产高清av在线一区二区三区 | 黄色一级毛片在线观看 | 久久视频热| 欧美一级二级三级视频 | 毛片视频网站在线观看 | 一本a道v久大 | 午夜小视频在线 | 香蕉久久夜色精品国产使用方法 | 精品国产一区二区 | 欧美精品1区| 成人刺激视频在线 | 一级毛片观看 | 久久精品国产v日韩v亚洲 | 色婷婷一区二区 | 日韩av免费在线播放 | 国产91久久精品一区二区 | 日韩一二三区视频 | 精品久久久久一区二区国产 | 国产欧美综合视频 | 伊人久久综合影院 | 欧美一区二区大片 | 日韩精品一区二区三区在线播放 | 久久99国产一区二区三区 | 日韩精品一区二区三区四区 | 99亚洲国产精品 | 久久精品一级毛片 | 国产精品久久久久国产精品 | 亚洲精品视频在线播放 | 操操网站 | 超碰伊人网 | 国产人成精品一区二区三 | 欧美 日韩 国产 在线 | 日韩免费在线 | av电影免费观看 | 色香蕉久久 | 欧美黄在线观看 | 精品久久久久久久久久久 | 国产精品精品视频 |