gin是什么?
Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧。
gin 为什么快?
我们先来看一下官方的基准测试 地址[1]

这只是其中的一部分,完整的可以自行进入上述地址进行查看。
我们通过性能测试看得出来 gin
在处理请求的性能上确实比其他的web
框架快上不少。gin
在处理请求的性能上确实比其他的web
框架快上不少。
性能问题主要是使用 httprouter[2],而httprouter
使用 Trie Tree
(字典树)作为路径存储结构,具有高性能的查找。
gin.Engine 源码
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings. // Create an instance of Engine, by using New() or Default() type Engine struct { RouterGroup // 用于注册根路由组使用 ... pool sync.Pool // 用于 gin.context 对象池 trees methodTrees // 用于保存的请求路径 ... }
在 gin 的Engine
httprouter
使用 Trie Tree
(字典树)作为路径存储结构,具有高性能的查找。🎜🎜🎜🎜gin.Engine 源码🎜// HandlerFunc defines the handler used by gin middleware as return value. type HandlerFunc func(*Context) // HandlersChain defines a HandlerFunc array. type HandlersChain []HandlerFunc // RouterGroup is used internally to configure router, a RouterGroup is associated with // a prefix and an array of handlers (middleware). type RouterGroup struct { Handlers HandlersChain basePath string engine *Engine root bool }🎜在 gin 的
Engine
中,最主要的就是这3个字段。🎜gin.RouterGroup 源码
// HandlerFunc defines the handler used by gin middleware as return value. type HandlerFunc func(*Context) // HandlersChain defines a HandlerFunc array. type HandlersChain []HandlerFunc // RouterGroup is used internally to configure router, a RouterGroup is associated with // a prefix and an array of handlers (middleware). type RouterGroup struct { Handlers HandlersChain basePath string engine *Engine root bool }
在RouterGroup
中Handlers
存放的是当前分组的所有中间件,也可以说:请求到这个分组,那么Handlers
中的函数都会根据索引从小到大的按顺序执行。
basePath
就是存放这个分组的基础路由路径。可能直接解释过于抽象;我们来分析它的调用链来看:
在gin.New()
函数中我们可以看到 basePath
默认是 /
而新的RouterGroup
是通过Engine
调用Group
函数产生的;也就是我们自己的Group
。

那么以后在这个Group
注册的路径都会自动加上/user
的路径。
为什么会自动添加路径,后面还会分析相关细节。
gin.methodTree 源码
type node struct { path string indices string wildChild bool nType nodeType priority uint32 children []*node // child nodes, at most 1 :param style node at the end of the array handlers HandlersChain fullPath string } type methodTree struct { method string root *node } type methodTrees []methodTree
对于node
的添加和查找我就不展开讲了,如果不懂的可以自行搜索字典树
和查看 httprouter[3] 的实现。
我们刚刚在gin.New
函数中可以看到,trees
是一个methodTree
的切片,并在在初始化给了默认容量为9
,是容量不是长度哦。

在addRoute
函数中可以看到trees
的添加:

如果开始没有对应方法的根路径node
对象,就会创建一个出来,然后再去添加对应的路由注册。node
对象,就会创建一个出来,然后再去添加对应的路由注册。
整体的流程分析
在gin
框架中,主要可以使用下面几种注册方式:
对应的http请求方法的名称( get,post,put...
)通过 Group
分组路由减少路径的填写通过 Any
注册所有http
方法路由
这些注册在下面其实都是调用的同一个方法,我们接下来就要来翻开她的外衣看看里面是什么样的。
可以看到都是调用的group.handle
整体的流程分析

gin
框架中,主要可以使用下面几种注册方式:对应的http请求方法的名称( get,post,put...
)通过 Group
分组路由减少路径的填写通过 Any
注册所有http
方法路由
这些注册在下面其实都是调用的同一个方法,我们接下来就要来翻开她的外衣看看里面是什么样的。
group.handle
方法🎜🎜🎜我们来看一下这个方法都做了哪些事情:🎜计算路由的路径 group.calculateAbsolutePath(relativePath)
group.calculateAbsolutePath(relativePath)
IRoutes
接口combineHandlers
支持最大的函数数量为63-1个
Group 函数
现在来看Group
的实现,通过调用这个方法会产生一个新的RouterGroup
并根据参数设置的基础路径,和全局engine
实体,并把基础的中间件也复制到其中。

使用分组路由最后也是调用group.handle
方法进行注册,只是其中的basePath
IRoutes
接口🎜combineHandlers
支持最大的函数数量为63-1个
Group 函数
🎜现在来看Group
的实现,通过调用这个方法会产生一个新的RouterGroup
并根据参数设置的基础路径,和全局engine
实体,并把基础的中间件也复制到其中。🎜
group.handle
方法进行注册,只是其中的basePath
在分组的时候已经设置好了,加上注册函数时的路径,就是这个请求的路由路径。🎜🎜需要注意的一点,我之前想过使用·Group·后,它后面的注册没有使用返回值,注册的路由是怎么注册到全局路由表中的,看过源码才明白。🎜
添加路由的时候,是获取的全局engine
实体,所以也是添加到全局路由表中的。
最后需要注意的
在使用注册中间件和注册路由的时候,需要注意他们注册的顺序。
上一点错误的注册方式代码:
package main import ( "github.com/gin-gonic/gin" ) func main() { eng := gin.New() eng.POST("login", func(context *gin.Context) { // 处理登录信息 }) eng.Use(gin.Logger()) userGroup := eng.Group("/user") userGroup.GET("info", func(context *gin.Context) { // 参数验证 // 处理逻辑 }) adminGroup := eng.Group("/admin") adminGroup.GET("info", func(context *gin.Context) { // 参数验证 // 处理逻辑 }) eng.Use(gin.Recovery()) adminGroup.PUT("info", func(context *gin.Context) { // 参数验证 // 处理逻辑 }) eng.GET("logout", func(context *gin.Context) { // 处理登录信息 }) eng.Run(":8080") }
运行结果:

可以看到在注册路由之后,再注册中间件,那么前面注册过的路由是没有这个中间件的。
以上是Gin Engine源码详解的详细内容。更多信息请关注PHP中文网其他相关文章!

goisidealforbuildingscalablesystemsduetoitssimplicity,效率和建筑物内currencysupport.1)go'scleansyntaxandaxandaxandaxandMinimalisticDesignenhanceProductivityAndRedCoductivityAndRedCuceErr.2)ItSgoroutinesAndInesAndInesAndInesAndineSandChannelsEnablenableNablenableNableNablenableFifficConcurrentscorncurrentprogragrammentworking torkermenticmminging

Initfunctionsingorunautomationbeforemain()andareusefulforsettingupenvorments和InitializingVariables.usethemforsimpletasks,避免使用辅助效果,andbecautiouswithTestingTestingTestingAndLoggingTomaintAnainCodeCodeCodeClarityAndTestesto。

goinitializespackagesintheordertheordertheyimported,thenexecutesInitFunctionswithinApcageIntheirdeFinityOrder,andfilenamesdetermineTheOrderAcractacractacrosmultiplefiles.thisprocessCanbeCanbeinepessCanbeInfleccessByendercrededBydeccredByDependenciesbetenciesbetencemendencenciesbetnependendpackages,whermayleLeadtocomplexinitialitialializizesizization

CustomInterfacesingoarecrucialforwritingFlexible,可维护,andTestableCode.TheyEnableDevelostOverostOcusonBehaviorBeiroveration,增强ModularityAndRobustness.byDefiningMethodSigntulSignatulSigntulSignTypaterSignTyperesthattypesmustemmustemmustemmustemplement,InterfaceSallowForCodeRepodEreusaperia

使用接口进行模拟和测试的原因是:接口允许定义合同而不指定实现方式,使得测试更加隔离和易于维护。1)接口的隐式实现使创建模拟对象变得简单,这些对象在测试中可以替代真实实现。2)使用接口可以轻松地在单元测试中替换服务的真实实现,降低测试复杂性和时间。3)接口提供的灵活性使得可以为不同测试用例更改模拟行为。4)接口有助于从一开始就设计可测试的代码,提高代码的模块化和可维护性。

在Go中,init函数用于包初始化。1)init函数在包初始化时自动调用,适用于初始化全局变量、设置连接和加载配置文件。2)可以有多个init函数,按文件顺序执行。3)使用时需考虑执行顺序、测试难度和性能影响。4)建议减少副作用、使用依赖注入和延迟初始化以优化init函数的使用。

go'SselectStatementTreamLinesConcurrentProgrambyMultiplexingOperations.1)itallowSwaitingOnMultipleChannEloperations,执行thefirstreadyone.2)theDefirstreadyone.2)thedefefcasepreventlocksbysbysbysbysbysbythoplocktrograpraproxrograpraprocrecrecectefnoopeready.3)

contextancandwaitgroupsarecrucialingoformanaginggoroutineseflect.1)context contextsallowsAllowsAllowsAllowsAllowsAllingCancellationAndDeadLinesAcrossapibiboundaries,确保GoroutinesCanbestoppedGrace.2)WaitGroupsSynChronizeGoroutines,确保Allimizegoroutines,确保AllizeNizeGoROutines,确保AllimizeGoroutines


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境