专题归档 · 2026 年 7 月(编辑分组,非实际写作日期)
Go 学习:从自己的项目代码开始看
先看 Go 基础,再阅读 User 请求链路、GORM 模型与 Gin Handler 的学习过程。
学习方式
前面先让 ai 去帮我整理了 go 的系列知识点 Go-MOC,看了 l3 以下等级,大致浏览后,学了 boot.dev 中的几门课程 Boot.dev Learn Go
开始在之前用 ai vibe 的实际项目中学习 go:
- 先看已有的代码
- 学实践中的新知识
- 把前面看到的知识点和实践结合
- 手搓新的代码
- 完善项目
- 应用
从项目的 User 流程开始
阅读了 user 相关的整个流程 http > handler > service > repository > model > postgresql
type User struct {
CreatedAt time.Time
LastLoginAt *time.Time
}
还有一个点就是其中的 last_login_at,它的类型是星号 time.Time。它为什么要使用指针类型呢?我后面了解到是因为 last_login_at 是可选字段,所以它可能是没有值的。而 Go 语言里面,就应该会需要用到指针类型,去使用 nil 来表示空值。如果是正常的非指针类型,没有值的话,会初始化为零值;而时间类型的零值,就是一个特殊值(即 0001-01-01 00:00:00 UTC),可能会导致误解或者错误。
留意到的 Go 写法
这里我关注到一个 Go 语言的特性: 在很多地方,Go 的写入方法与 JS 等语言有所不同。一般情况下,在 JS 中都是通过方法返回值,再赋值给定义的变量;但在 Go 里面,存在很多方法是需要你传入一个变量的指针(地址),然后直接将值写入到该地址对应的变量中。这里确实很有 Go 语言的独特特性。
c *gin.Context 这里是一个传入的参数。我看了一下,是基于一个 Go 的框架 GIN。这个框架本质上是建立在 Go 的基础框架 net/http 这个基础库上,然后进行了一层封装。是一个为一次 HTTP 请求准备的综合工作台。它封装主要是对 http.Request, ResponseWriter, Router, Middleware 状态做了一层便利封装。
后续阅读
关于为什么开始看其他开源项目源码,另记在 Go 开源源码阅读。