Go Gin源码学习(五)

栏目: Go · 发布时间: 5年前

内容简介:经过上一篇的学习笔记,我们已经知道了Gin router的主要流程。但是我们看到代码和方法体总体很长,其中大部分是参数路由的判断。这些零散的小逻辑,让我们阅读源码的时候更难理解了一些。但是其实基数树的逻辑兵没有这么的复杂,所以我们还是按照老规矩,自己实现以下这个简单的基数树值包含主流程。代码如下:上面的代码已经不需要太多的注释了,去掉了参数节点的代码整个流程已经很明确了。Gin的源码学习和分析已经全部结束了。其实对于Gin框架源码的分析已经有了很多文章,但是如果在学习的同时自己也简单的模仿和实现一下这些功能

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 Gin源码学习(五)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

颠覆式创新:移动互联网时代的生存法则

颠覆式创新:移动互联网时代的生存法则

李善友 / 机械工业出版社 / 2015-3-1

为什么把每件事情都做对了,仍有可能错失城池?为什么无人可敌的领先企业,却在一夜之间虎落平阳?短短三年间诺基亚陨落,摩托罗拉以区区29亿美元出售给联想,芯片业霸主英特尔在移动芯片领域份额几乎为零,风光无限的巨头转眼成为被颠覆的恐龙,默默无闻的小公司一战成名迅速崛起,令人瞠目结舌的现象几乎都能被“颠覆式创新”法则所解释。 颠覆式创新教你在新的商业竞争中“换操作系统”而不是“打补丁”,小公司用破坏......一起来看看 《颠覆式创新:移动互联网时代的生存法则》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具