Gin(二):路由Router

GIN---router 根据gin中文文档有使用 GET, POST, PUT, PATCH, DELETE, OPTIONS。1. 首先创建一个demo,然后在控制台使用下面语句,引入gin包。2. 在demo.go中开始编写第一个初始gin函数。通过localhost:8080/即可访问。经典hello world的编写。 阅读详情

经过上一章节的介绍,搭建一个简单的 Gin web 项目非常容易,同时也引入了一些新的概念,比如说:路由 Router。

路由是一个非常重要的概念,所有的接口都要有路由来进行管理。

?请求方法

Gin 的路由支持 GET , POST , PUT , DELETE , PATCH , HEAD , OPTIONS 请求,同时还有一个 Any 函数,可以同时支持以上的所有请求。

将上一章节的代码添加其他请求方式的路由,并编写单元测试。

// 省略其他代码
// 添加 Get 请求路由
router.GET("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin get method")
})
// 添加 Post 请求路由
router.POST("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin post method")
})
// 添加 Put 请求路由 
router.PUT("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin put method")
})
// 添加 Delete 请求路由
router.DELETE("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin delete method")
})
// 添加 Patch 请求路由
router.PATCH("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin patch method")
})
// 添加 Head 请求路由
router.HEAD("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin head method")
})
// 添加 Options 请求路由
router.OPTIONS("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin options method")
})
// 省略其他代码

单元测试,只展示一个 Post 请求函数,基本与 Get 请求一致,其他代码详见文末 Github 地址。

// router("/") post 测试
func TestIndexPostRouter(t *testing.T) {
	router := initRouter.SetupRouter()
	w := httptest.NewRecorder()
	req, _ := http.NewRequest(http.MethodPost, "/", nil)
	router.ServeHTTP(w, req)
	assert.Equal(t, http.StatusOK, w.Code)
	assert.Equal(t, "hello gin post method", w.Body.String())
}

此时运行单元测试,所有测试完美通过。

但是也有一个问题,所有的请求对应的路由内函数基本一样,只是有细微的差别,但是我们却每个路由里都完完整整的写了一遍,所以我们要将公共逻辑抽取出来。

func retHelloGinAndMethod(context *gin.Context) {
	context.String(http.StatusOK, "hello gin "+strings.ToLower(context.Request.Method)+" method")
}

我们将方法的公共部分抽取出来,并通过 context.Request.Method 将请求的方法提取出来 ,并将其转化为小写。此时就可以改造我们的路由了,将原有的路由中的函数去掉换成我们所编写的新的函数。

// 添加 Get 请求路由
router.GET("/", retHelloGinAndMethod)
// 添加 Post 请求路由
router.POST("/", retHelloGinAndMethod)
// 添加 Put 请求路由
router.PUT("/", retHelloGinAndMethod)
// 添加 Delete 请求路由
router.DELETE("/", retHelloGinAndMethod)
// 添加 Patch 请求路由
router.PATCH("/", retHelloGinAndMethod)
// 添加 Head 请求路由
router.HEAD("/", retHelloGinAndMethod)
// 添加 Options 请求路由
router.OPTIONS("/", retHelloGinAndMethod)

此时运行单元测试,仍旧是完美通过。

?Handler 处理器

经过上面简单的例子的演示和操作,现在我们大概可以了解到路由需要传入两个参数,一个为路径,另一个为路由执行的方法,我们叫做它处理器 Handler ,而且,该参数是可变长参数。也就是说,可以传入多个 handler,形成一条 handler chain 。

同时对 handler 该函数有着一些要求,该函数需要传入一个 Gin.Context 指针,同时要通过该指针进行值得处理。

Handler 函数可以对前端返回 字符串,Json,Html 等多种格式或形式文件,之后我们会慢慢逐一介绍。

?获取路由路径中参数

知道了路由支持的方法和对应的处理器,那么接下来就应该了解如何从路由中获取参数。

编写一个新的路由,如下:

//省略其他代码	
// 添加 user
router.GET("/user/:name",handler.Save)
// 省略其他代码

此时我们发现,在原来只有 / 分隔符的情况下出现了 /: 该符号就表示后面的字符串为一个占位符,用于将要进行的传值。,此时我们的路由为 /user/{name}

我们没有必要把所有的 Handler 都写到一个文件夹中,那样会臃肿不堪,所以我们新建一个文件夹handler,在文件夹下建立 userHandler.go 文件,编写该文件。

package handler

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func UserSave(context *gin.Context) {
	username := context.Param("name")
	context.String(http.StatusOK, "用户已经保存")
}

同样,我们用 context.Param 可以获取路由路径中的参数。

此时,就可以编写我们的单元测试。

新建立一个 user_test.go 文件。

func TestUserSave(t *testing.T) {
	username := "lisi"
	router := initRouter.SetupRouter()
	w := httptest.NewRecorder()
	req, _ := http.NewRequest(http.MethodGet, "/user/"+username, nil)
	router.ServeHTTP(w, req)
	assert.Equal(t, http.StatusOK, w.Code)
	assert.Equal(t, "用户"+username+"已经保存", w.Body.String())
}

运行单元测试,测试通过。同样我们可以运行我们的项目在浏览器中输入 localhost:8080/user/lisi 在浏览器页面上也可以看到 用户lisi已经保存

当然,获取参数的方法不止这一个。针对不同的路由,Gin 给出了不同的获取参数的方法,比如形如:/user?name=lisi&age=18。

我们再次添加一个 Handler,做为处理。在 userHandler 中添加下面的方法。

// 通过 query 方法进行获取参数
func UserSaveByQuery(context *gin.Context) {
	username := context.Query("name")
	age := context.Query("age")
	context.String(http.StatusOK, "用户:"+username+",年龄:"+age+"已经保存")
}

同时对路由进行添加和完善。

router.GET("/user", handler.UserSaveByQuery)

完成路由之后,就可以重新编写单元测试,完善项目。

func TestUserSaveQuery(t *testing.T) {
	username := "lisi"
	age := 18
	router := initRouter.SetupRouter()
	w := httptest.NewRecorder()
	req, _ := http.NewRequest(http.MethodGet, "/user?name="+username+"&age="+strconv.Itoa(age), nil)
	router.ServeHTTP(w, req)
	assert.Equal(t, http.StatusOK, w.Code)
	assert.Equal(t, "用户:"+username+",年龄:"+strconv.Itoa(age)+"已经保存", w.Body.String())
}

运行测试,测试通过。并且可以通过 浏览器访问localhost:8080/user?name=lisi,页面上打印出用户:lisi,年龄:18已经保存 。

当然,还可以通过 context.DefaultQuery 方法,在获取时,如果没有该值则赋给一个默认值。

重新修改获取年龄的代码,将其改为以下代码

age := context.DefaultQuery("age", "20")

重新编写我们的单元测试,并运行。

func TestUserSaveWithNotAge(t *testing.T) {
	username := "lisi"
	router := initRouter.SetupRouter()
	w := httptest.NewRecorder()
	req, _ := http.NewRequest(http.MethodGet, "/user?name="+username, nil)
	router.ServeHTTP(w, req)
	assert.Equal(t, http.StatusOK, w.Code)
	assert.Equal(t, "用户:"+username+",年龄:20已经保存", w.Body.String())
}

同样也可以通过浏览器访问 /user?name=lisi 可以看到浏览器上显示 用户:lisi,年龄:20已经保存 。

当然,还提供了其他参数获取方法, QueryArray 获取数组和 QueryMap 获取 map。

?路由分组

此时我们再次看 SetupRouter 方法时,里面的路由基本可以分为两大类 / 和 /user,如果日后在进行功能的添加,那么势必会出现大量的路由,所以我们需要对路由进行一下管理,Gin 给我们提供了路由分组。

先把 / 的路由写到一起,运行 index_test.go 单元测试。

index := router.Group("/")
{
    // 添加 Get 请求路由
    index.GET("", retHelloGinAndMethod)
    // 添加 Post 请求路由
    index.POST("", retHelloGinAndMethod)
    // 添加 Put 请求路由
    index.PUT("", retHelloGinAndMethod)
    // 添加 Delete 请求路由
    index.DELETE("", retHelloGinAndMethod)
    // 添加 Patch 请求路由
    index.PATCH("", retHelloGinAndMethod)
    // 添加 Head 请求路由
    index.HEAD("", retHelloGinAndMethod)
    // 添加 Options 请求路由
    index.OPTIONS("", retHelloGinAndMethod)
}

通过 router.Group 返回一个新的分组路由,通过新的分组路由把之前的路由进行简单的修改。当然分组里面仍旧可以嵌套分组。

之前在请求方法中说到有一个 Any 函数可以通过任何请求,此时我们就可以把 index 里面所有的请求替换为 Any

index := router.Group("/")
{
    index.Any("", retHelloGinAndMethod)
}

运行单元测试,测试都可以通过。

此时也发现了单元测试的好处,虽说之前花费了时间和经历编写了单元测试,但是日后的功能上修改,只需要进行运行单元测试就可以知道我们的功能是否正确,在后期的功能测试上大大减少了经历和时间。

同样我们把 user 也进行分组,分组不仅仅是将相同逻辑的代码放到一起,而且可以提供相同的路由前缀,修改后的路由仍旧和之前一致。运行单元测试 user_test.go ,单元测试可以完全通过,证明我们的代码没有问题。

userRouter := router.Group("/user")
{
    userRouter.GET("/:name", handler.UserSave)
    userRouter.GET("", handler.UserSaveByQuery)
}

✍总结

通过简单的路由的使用,基本明白了路由在 Gin 中的地位,也对一些常见的使用方式有了一些直观的认识。

?‍?本章节代码

Github

个人公众微信号

文章与个人公众号同步更新,欢迎各位扫码关注。

在这里插入图片描述

Golang Gin框架搭建项目(一)基础框架、router、controller、参数接收 Golang Gin框架搭建项目,router配置,controller,各种参数接收 阅读详情

相关推荐

深入Gin框架内幕(一)

Gin框架介绍 Gin是一个用 Go (Golang) 编写的 web 框架。它是一个类似于martini但性能更好的API框架,不同于谢大主导的Beegoweb框架,后者更像是Python语言中的Django框架,内部包含了开发一个web程序所需的各种组件。 如果你是性能和高效的追求者,我相信你会像我一样爱上Gin。 同时,不同于其他Golang语言的API框架,该框架社区十分活跃,并且主程仍然...

weichuangxxb的博客 2605

gin之router

gin的是路由算法其实就是一个Trie树(也就是前缀树) 一、注册路由 1、普通注册 2、使用中间件 3、使用Group(路由组) 在预处理阶段 1、在调用中间件的时候, 是将某个路由的handler处理函数和中间件的处理函数都放在了Handlers的数组中 2、在调用Group的时候, 是将路由的path上面拼上Group的值. 也就是/user/:name, 会变成v1/user:name 最后都需要handle的addRoute注册到e...

heshushun的博客 1894

ADS2016子电路封装避坑指南:手把手教你制作可复用的自定义Symbol

本文详细介绍了在ADS2016中制作可复用的自定义Symbol的全流程,重点解析了子电路封装的常见问题与解决方案。从电路模块的标准化处理、Hierarchy创建技巧到Symbol视觉优化和库管理策略,帮助工程师提升射频与微波电路设计效率。特别针对Symbol比例适配和引脚优化等核心问题,提供了实用的避坑指南和工程验证方法。

weixin_30275415的博客 218

golang语言web开发01-之 gin框架的路由router管理示例

1、gin文档gin 是golang语言开发的一个web框架,文章也选取这个框架进行描述 2、一个关于golang web 开发用到的案例 3、go语言圣经golang 基础go 的环境安装这里没做介绍提示:以下是本篇文章正文内容, (1)路由管理这一模块完美管理(2)最麻烦的就是后面的总路由管理,那里有些绕,需要沉下心来感受感受,梳理梳理。

weixin_51604181的博客 1648

翻倍密码系统主图指标-行情买卖以及持股-翻倍密码买点-获利了结,通达信炒股软件指标公式

华森制药,上图案例走势,低位出现“开始潜伏”信号,进场红色K线持股待涨,进入“翻倍密码买点”,开启紫色K线的持续上涨,目前也达到了翻倍行情,还没出现“获利了结”的出场信号。这套操盘系统,即便出现信号没走出翻倍行情,也都是可以全身而退,获利出局,或者微微止损出场,并不代表每一个波段都能翻倍,但是走翻倍行情,你按照信号参与或持仓是不会错过的。用这个操盘系统操作,你也不需要天天的盘中看盘,不需要担心盘中的震荡,只要趋势不变,哪怕是偶尔出现跌停,也不影响行情的继续上涨,这都是上涨途中的正常调整。

weixin_69760830的博客 3682

白话详细解读(七)----- CBAM:Convolutional Block Attention Module

一、CBAM简介 论文链接:https://x.sci-hub.org.cn/scholar?hl=zh-TW&as_sdt=0%2C5&q=CBAM%3A+Convolutional+Block+Attention+Module&btnG=&oq=CB CBAM这篇论文是在2018年提出的,自提出之后,已经被引用上千次,可见其影响力。CBAM是一种专门为了卷积神经网络而设计的注意力模块,传统的卷积存在只关注局部信息,而往往忽略全局信息的弊端,以3*3卷积为例,滤波器有9个

奋斗の博客 1万+

gin框架httprouter路由原理

gin的路由注册采用的是httprouter。httprouter是基于radix tree实现的前缀匹配。其路由的原理是大量使用公共前缀的树结构,具有公共前缀的节点也共享一个公共父节点。每一种http方法一个 radix tree,这样可以提高匹配效率;

sre救赎之路 1429

从零构建腾讯滑块验证码破解引擎:逆向工程与实战对抗

本文深入解析腾讯滑块验证码(原天御验证码)的防护机制,包括环境感知层、行为分析层和验证决策层的核心技术。通过JSVMP虚拟机保护、轨迹验证算法和动态加密体系,腾讯验证码实现了高效的人机识别。文章还提供了安全研究实践指南,涵盖环境模拟和验证码识别方案,并探讨了防御对抗的演进趋势与合规研究建议。

rl6adventurer的博客 831

ajax delete gin 获取不到_Gin(二):路由Router

文章首发于 Gin(二):路由Router | ISLAND​youngxhui.top经过上一章节的介绍,搭建一个简单的 Gin web 项目非常容易,同时也引入了一些新的概念,比如说:路由 Router。路由是一个非常重要的概念,所有的接口都要有路由来进行管理。请求方法Gin 的路由支持 GET , POST , PUT , DELETE , PATCH , HEAD , OPTIONS 请求...

weixin_32284931的博客 257

芒果YOLO11改进23:主干Backbone篇GhostNet:原创改进高效 GhostNet 网络,华为出品,打造全新检测器

主干Backbone篇GhostNet:原创改进高效 GhostNet 网络,华为出品,打造全新检测器

包括YOLOv5、YOLOv7、YOLOv8等模型改进 406

github创建账号第一步始终出错

github创建账号总结:第一次注册GitHub,填好用户名邮箱密码后进入下一步就卡在哪里,上面还提示Unable to verify your captcha response等,进入网址的解决办法以及下载其他的浏览器也无法解决,用手机浏览器抱着试一试的心态竟然成功了,分享给大家。手机下载谷歌浏览器,进入GitHub正常注册,能向下继续,邮箱验证完以后再用电脑登陆就ok啦

计算机毕业论文源码,学生个人网页制作html源码。贴近用户做网络推广和互联网优化。 4376

知识分享之Golang——Gin学习之Router路由的使用(二)

知识分享之Golang——Gin学习之Router路由的使用(二) 背景 知识分享之Golang篇是我在日常使用Golang时学习到的各种各样的知识的记录,将其整理出来以文章的形式分享给大家,来进行共同学习。欢迎大家进行持续关注。 知识分享系列目前包含Java、Golang、Linux、Docker等等。 开发环境 系统:windows10 语言:Golang 组件库:Bleve golang版...

CN華少的博客 2054

深入解析:AndroidManifest.xml 与 Qt 6.7.0 的整合

本文探讨了在Qt 6.7.0和CMake构建Android应用时,AndroidManifest.xml未被正确识别的问题。通过分析CMake配置错误、文件路径问题等可能原因,提出了在CMakeLists.txt中明确指定路径、确保目录结构正确等解决方案,并给出了示例项目演示。文章强调正确配置AndroidManifest.xml对获取权限和应用功能的重要性,为Qt开发者提供了实用的调试建议。

2501_90323865的博客 110

高度解耦的gin路由中间件gin-auto-router,实现自动路由添加

项目地址 Github地址https://github.com/dengshulei/gin-auto-router Gitee地址https://gitee.com/dengshulei/gin-auto-router 项目目标 1. 路由自动注册,不用每次都手动添加 2. 将精力放到具体业务逻辑开发上来 3. 降低新手的入门难度 注意事项 暂时只实现了post请求方式,这也是在生产中推荐使用的方式,其它方式可以参考代码自己实现,比较简单。 简要描述 开发人员只需要编辑controller相关文件Arti

Tristone的博客 2945

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

优化 gin router 生成restful APi 在router文件中路由过多问题

然而gin中路由定义只有GET,POST,DELETE,PATCH,PUT,OPTIONS,没有Resource 为此我查看了一下github.com\gin-gonic\gin@v1.9.0\routergroup.go 下的文件各个方法的定义,实现方式大差不差。楼主之前是使用PHP的,这几个月在学习go,最近在使用Gin开发过程中遇到了一个问题,在生成restful 风格Api时,往往需要重复书写路由例如。以上就是对以上gin restful风格API的优化,不过上述也存在一些缺点,

祥富大大的博客 480

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

gin | gin路由

gin | gin路由

Mopes__的博客 1123

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Gin路由基础

gin 框架的基本使用 把对应的数据解析好结构体中,需要在结构体中配置相应的配置,才能正常使用ShouldBind系列方法。客户端传参,后端接收并解析到结构体定。

go|Python的个人博客 2155

go web框架 gin-gonic源码解读02————router

net/http 包的路由定义相对简单,只能通过 http.HandleFunc 或 http.Handle 来定义路由处理函数。这导致难以支持复杂的路由模式,如正则表达式匹配、参数提取等。

J1nAB1n9的博客 1353

Gin源码解析和例子——路由

Gin是一个基于golang的net包实现的网络框架。从github上,我们可以看到它相对于其他框架而言,具有优越的性能。本系列将从应用的角度来解析其源码。(转载请指明出于breaksoftware的csdn博客) 本文我们将分析其路由的原理。先看个例子(源于github) func main() { // Disable Console Color //...

方亮的专栏 6957

告别路由混乱:Gin路由分组技术让大型项目架构清晰如镜

你是否也曾面对这样的困境:随着项目规模扩大,API路由像一团乱麻般纠缠不清?新功能开发时找不到对应路由位置,修改一处路由却意外影响其他功能,团队协作时因路由命名冲突频繁扯皮? Gin框架的路由分组(Router Group)功能正是为解决这些痛点而生,它能将复杂项目的路由系统梳理得井然有序,让代码维护成本直线下降。本文将从实际场景出发,带你掌握路由分组的设计思想与实战技巧,轻松应对大型项目的路由管...

gitblog_01031的博客 1184

Gin框架路由组(Router Group)详解:构建模块化API的最佳实践

为一组路由定义公共路径前缀为特定路由集合应用中间件实现API版本控制按功能模块组织代码结构。

Java程序员_编程开发学习笔记_网站安全运维教程_渗透技术教程 996

【Golang】gin框架创建路由源码分析

逐步分析了gin框架创建路由方法的源码

Valour616的博客 1650

深入浅出:Gin框架路由与HTTP请求处理

路由(Routing)是指根据URL路径和HTTP方法(如GET、POST等),将请求分发到相应的处理函数的过程。Gin框架通过其简洁的API,使得路由定义变得非常直观和易于管理。import (// 创建一个新的Gin路由器// 定义一个简单的GET路由",})})// 启动HTTP服务器,监听8080端口在这个例子中,我们创建了一个GET路由,当用户访问根路径时,返回一个JSON响应,包含消息。我们可以轻松地定义多个路由,每个路由对应不同的URL路径和HTTP方法。")})

软件架构师笔记 1362

gin:包管理和路由拆分

gin的路由拆分,实际就是路由模块化分组。使用路由拆分的目的在于提高代码的可读性。开发中没有银弹,没有完美的解决方案

jayLog的博客 1475

自动路由组件 gin-auto-router 升级 到了1.3.0 项目是基于 Golang 语言 Gin 框架开发的 并同步在 github 和 gitee 发布

文章摘要: gin-auto-router 是一个专为 Gin 框架设计的自动路由组件,支持 Golang 开发。它通过自动注册路由简化开发流程,兼容所有 RESTful API 请求类型(如 GET/POST/PUT/DELETE),并支持多种命名规范(kebab-case、snake_case、camelCase 等)。最新 v1.3.0 版本优化了路由绑定逻辑,默认采用短横线命名法,同时保持向后兼容。开发者可通过两种方式集成:1)基础路由模式自动绑定;2)分组路由模式结合中间件(如 JWT 鉴权)。

Tristone的博客 57
上一篇: Gin(一):Hello
下一篇: Gin(三):模板tmpl
代码猎奇站
博客等级 码龄7年 39粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值