Go Gin源码学习(五)

panlei914 · · 436 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
### Gin路由主要流程实现 经过上一篇的学习笔记,我们已经知道了Gin router的主要流程。但是我们看到代码和方法体总体很长,其中大部分是参数路由的判断。这些零散的小逻辑,让我们阅读源码的时候更难理解了一些。但是其实基数树的逻辑兵没有这么的复杂,所以我们还是按照老规矩,自己实现以下这个简单的基数树值包含主流程。代码如下: ``` package mygin import "fmt" type Trees map[string]*node type node struct { path string indices string children []*node handlers HandlerList } func (n *node) addRoute(path string, handlers HandlerList) { if len(n.path) > 0 || len(n.children) > 0 { walk: for { //找到相等的index i := 0 max := min(len(path), len(n.path)) for max > i && path[i] == n.path[i] { i++ } //需要把原来的作为子node放到新node中 if i < len(n.path) { //新建node child := node{ path: n.path[i:], indices: n.indices, handlers: n.handlers, children: n.children, } n.children = []*node{&child} n.indices = string([]byte{n.path[i]}) n.path = path[:i] n.handlers = nil } // 判断子节点如果有相同开头的字符 则从新跳入循环 if i < len(path) { c := path[i] for index := 0; index < len(n.indices); index++ { if c == n.indices[index] { n = n.children[index] path = path[i:] continue walk } } //把新请求的path加入到router中 n.insertChild(path[i:], path, handlers, i) return } return } } else { //如果为空 n.path = path n.handlers = handlers } } func (n *node) insertChild(path, fullPath string, handlers HandlerList, index int) { child := node{} child.handlers = handlers child.indices = "" child.path = path n.indices += string([]byte{fullPath[index]}) n.children = append(n.children, &child) } func min(a, b int) int { if a > b { return b } return a } func (n *node) getValue(path string) (handlers HandlerList) { index := 1 walk: for { fmt.Println("loop num: ", index) if len(path) > len(n.path) { path = path[len(n.path):] c := path[0] for i := 0; i < len(n.indices); i++ { if c == n.indices[i] { n = n.children[i] index++ goto walk } } } else if len(path) == len(n.path) { handlers = n.handlers return } } } ``` ### 总结 上面的代码已经不需要太多的注释了,去掉了参数节点的代码整个流程已经很明确了。 ### 结束语 Gin的源码学习和分析已经全部结束了。其实对于Gin框架源码的分析已经有了很多文章,但是如果在学习的同时自己也简单的模仿和实现一下这些功能对于我们理解就更有帮助。 Gin是一个十分轻巧http框架,代码也十分的简介和清楚。实现也有一些亮点,我觉得很适合新手对于go源码学习和分析的入门框架。希望这5篇文章能对在学习go中的人有一些帮助。

入群交流(和以上内容无关):Go中文网 QQ 交流群:729884609 或加微信入微信群:274768166 备注:入群;关注公众号:Go语言中文网

436 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传