跳至主要內容

go|gin 快速复习

程序员李某某原创Gogoadmin大约 3 分钟

go|gin 快速复习

说明

这个笔记主要是go学习了多半年,但是一直没有做项目,导致基本忘光,一边看go-admin项目,一边回顾相关知识

官网第一个示例

背景

在写go-admin官方文档第一个示例时,代码如下

handler

// go-admin/app/admin/apis/article.go
package apis

import (
 "github.com/gin-gonic/gin"
 "go-admin/common/apis"
)

type Article struct {
 apis.Api
}

// GetArticleList 获取文章列表
func (e Article)GetArticleList(c *gin.Context) {
 err := e.MakeContext(c).
  Errors
 if err != nil {
  e.Logger.Error(err)
  return
 }
 e.OK("hello world !","success")
}

router

// go-admin/app/admin/router/article.go
package router

import (
 "go-admin/app/admin/apis"

 "github.com/gin-gonic/gin"
 jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
)

func init() {
 routerCheckRole = append(routerCheckRole, registerArticleRouter)
}

// 需认证的路由代码
func registerArticleRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
 api:= apis.Article{}
 r := v1.Group("")
 {
  r.GET("/articleList", api.GetArticleList)
 }
}

gin-路由

路由中的这段代码还是很好理解的

func registerArticleRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
	api := apis.Article{}
    // 
    /*
    初学gin时,*gin.RouterGroup 是通过 
        r := gin.Default()     拿到*gin.Engine,
        g := r.Group("")       再调用Group()方法拿到的
    这里直接作为参数传入
    */
	r := v1.Group("")
	{
		r.GET("/articleList", api.GetArticleList)
	}
}

这个方法被添加到了routerCheckRole 这个全局变量中

func init() {
	routerCheckRole = append(routerCheckRole, registerArticleRouter)
}

那routerCheckRole是什么呢,是这个东西make([]func(*gin.RouterGroup), 0) --- 一个元素为函数的切片

先复习下 go-内存分配

引用关系

app/admin/router/init_router    func InitRouter() 
引用了
app/admin/router/router         func InitExamplesRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine
引用了
app/admin/router/router         func examplesNoCheckRoleRouter(r *gin.Engine)
引用了                           我们自定义的路由
func examplesNoCheckRoleRouter(r *gin.Engine) {
    // 看看看,没错吧 --- 遍历拿到了自定义的路由函数,入参就是 *gin.Engine.Group("/api/v1")
	v1 := r.Group("/api/v1")
	for _, f := range routerNoCheckRole {
        // 调用自定义路由的函数
		f(v1)
	}
}

go-内存分配

// app/admin/router/router.go
var (
	routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
	routerCheckRole   = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
)

Go 语言中的内存分配是由运行时系统(runtime)负责管理的。它使用了自动垃圾回收(Garbage Collection)来处理内存的分配和释放。

在 Go 中,可以使用 new 或 make 关键字来分配内存

  • 使用 new 关键字分配内存(用于分配指定类型的内存,返回内存地址,改值必须解引用)

    var p *int
    p = new(int)
    *p = 42
    
  • 使用 make 关键字分配内存(用于内置引用类型):

      slice1 := make([]int, 10)           // 切片:长度10,容量(底层数组长度10)
      slice2 := make([]int, 0, 10)        // 切片:长度0,容量(底层数组长度10)
    
      m := make(map[string]int)           // 映射:初始容量为0
      map1 := make(map[string]string,10)  // 映射:初始容量为10
    
      ch := make(chan int)                    // 管道:无缓冲、同步、阻塞
      chanInt = make(chan int, 4)             // 管道:缓冲区容量4,写未满不阻塞,读非空不阻塞
      chanInt1 = make(chan<- int, 5)          // 只写管道
      chanInt2 = make(<-chan int, 6)          // 只读管道
    
      // 再看go-admin中的
      // 定义了一个初始长度为0的切片
      // 切片的元素是函数(入参为*gin.RouterGroup,无返回值)
      routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
    
    

gin-其他

问题解决

Goland Debug

Version of Delve is too old for Go version 1.20.0 (maximum supported version 1.19)

这是 Goland 的 Dug

  • 最简单粗暴的方法是升级 Goland 版本
  • 方法二:
    • 下载安装 dlv
      go install github.com/go-delve/delve/cmd/dlv@latest
      
    • 配置 GoLand -> Help -> Edit Custom Properties
      # 执行上述安装命令或默认安装到GOPATH目录下,即go安装路径
      # Linux 可以执行 which dlv 查看路径
      # Windows 可以执行 where dlv 查看路径
      dlv.path=D:\\dev-tool\\go-1.21.5\\bin\\dlv.exe
      
    • 重启 Goland
上次编辑于:
贡献者: ext.liyuanhao3