跳到主要内容

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 做了什么?

答案

  1. 分析代码中实际导入的包
  2. 添加缺失的 require
  3. 删除不再使用的 require
  4. 更新 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),可以同时存在。

相关链接