Go Modules
问题
Go Modules 是怎么工作的?go.mod 和 go.sum 的作用是什么?
答案
基本操作
# 初始化模块
go mod init github.com/user/project
# 添加依赖(自动修改 go.mod)
go get github.com/gin-gonic/gin@latest
go get github.com/gin-gonic/gin@v1.9.1 # 指定版本
# 整理依赖(删除未使用的)
go mod tidy
# 下载依赖到本地缓存
go mod download
# 更新所有依赖
go get -u ./...
go.mod 文件
module github.com/user/project
go 1.22
require (
github.com/gin-gonic/gin v1.9.1
gorm.io/gorm v1.25.0
)
require (
// indirect 表示间接依赖(依赖的依赖)
github.com/bytedance/sonic v1.9.1 // indirect
)
// 替换依赖(本地开发/fork 修复)
replace github.com/old/pkg => github.com/new/pkg v1.0.0
replace github.com/some/pkg => ../local-pkg
go.sum
go.sum 记录每个依赖的哈希校验值,保证依赖不被篡改:
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPt...
github.com/gin-gonic/gin v1.9.1/go.mod h1:RDnlIIBx...
安全
go.sum 必须提交到版本控制。它是依赖完整性校验的关键,防止供应链攻击。
版本选择规则
Go Modules 使用 MVS(Minimum Version Selection):
A 依赖 B v1.2.0
A 依赖 C
C 依赖 B v1.3.0
MVS 选择 B v1.3.0(满足所有要求的最小版本)
私有模块
# 设置私有仓库不走代理
go env -w GOPRIVATE=github.com/mycompany/*
# GOPROXY 设置(国内加速)
go env -w GOPROXY=https://goproxy.cn,direct
常见面试问题
Q1: go mod tidy 做了什么?
答案:
- 分析代码中实际导入的包
- 添加缺失的
require - 删除不再使用的
require - 更新 go.sum
Q2: replace 的使用场景?
答案:
- 本地开发:
replace github.com/pkg => ../local-pkg - Fork 修复:上游有 Bug,用 fork 版本替换
- 内部代理:将公共包指向内部镜像
警告
replace 只在主模块的 go.mod 生效,作为库被引用时 replace 会被忽略。
Q3: 如何处理菱形依赖冲突?
答案:Go Modules 的 MVS 策略天然解决:选满足所有要求的最小版本。如果版本不兼容(v2 vs v1),Go 通过模块路径区分大版本(github.com/pkg/v2),可以同时存在。