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

查看所有标签

猜你喜欢:

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

Boolean Reasoning

Boolean Reasoning

Brown, Frank Markham / 2003-4 / $ 19.15

A systematic treatment of Boolean reasoning, this concise, newly revised edition combines the works of early logicians with recent investigations, including previously unpublished research results. Th......一起来看看 《Boolean Reasoning》 这本书的介绍吧!

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

html转js在线工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具