Go Gin源码学习(五)

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

内容简介:经过上一篇的学习笔记,我们已经知道了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源码学习(五)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

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

数学与生活(修订版)

数学与生活(修订版)

[日] 远山启 / 吕砚山、李诵雪、马杰、莫德举 / 人民邮电出版社 / 2014-10 / 42.00元

数学是高等智慧生物的共有思维,是对真理的探索,对矛盾的怀疑,但它绝非一门晦涩难懂的学问,非应试目的的数学是纯粹而朴实的智慧。《数学与生活》为日本数学教育改革之作,旨在还原被考试扭曲的数学,为读者呈现数学的真正容颜,消除应试教学模式带来的数学恐惧感。 本书既包含了初等数学的基础内容,又包含了微分、积分、微分方程、费马定理、欧拉公式等高等数学的内容。作者运用了多个学科的知识。结合日常生活和东西方......一起来看看 《数学与生活(修订版)》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码