Go Modules 包管理详解:go.mod、go.sum 与依赖管理

作者:程序员爱钓鱼日期:2026/7/26

Go 编程实战系列(五)

上一篇《第一个 Go 程序:Hello World》中,我们创建了第一个 Go 项目,并执行过这样一条命令:

1go mod init hello-go
2

执行完成后,项目目录中会出现一个 go.mod 文件。

很多初学者第一次看到它时可能会疑惑:

go.mod 到底有什么用?Go 项目的第三方库从哪里下载?为什么有时还会出现 go.sum?go get 和 go mod tidy 又有什么区别?

这些问题都与 Go Modules 有关。

Go Modules 是现代 Go 项目管理模块和第三方依赖的核心机制。无论以后开发 Gin Web 服务、GORM 数据库项目,还是大型微服务,都离不开它。


一、什么是 Go Modules?

在实际项目中,我们不可能所有功能都自己实现。

例如开发 Web 项目时可能使用:

1Gin
2GORM
3Redis
4JWT
5Zap
6Viper
7

这些第三方库都需要下载、记录版本并管理依赖关系。

Go Modules 就是 Go 官方提供的模块和依赖管理机制。

它主要解决以下问题:

  • 项目依赖哪些第三方库?
  • 每个依赖使用哪个版本?
  • 第三方库从哪里下载?
  • 不同项目如何使用不同依赖版本?
  • 如何保证其他开发者构建出相同的项目?

Go Modules 的核心文件主要有两个:

1go.mod
2go.sum
3

其中:

go.mod 管理模块信息和依赖版本。

go.sum 用于记录依赖内容的校验信息。


二、创建 Go Modules 项目

首先创建项目:

1mkdir go-module-demo
2cd go-module-demo
3

初始化:

1go mod init go-module-demo
2

执行后会生成:

1go.mod
2

内容类似:

1module go-module-demo
2
3go 1.xx
4

第一行:

1module go-module-demo
2

表示当前模块名称。

第二行:

1go 1.xx
2

记录模块声明的 Go 语言版本信息。

项目结构:

1go-module-demo
2├── go.mod
3└── main.go
4

这样,一个最基本的 Go Modules 项目就创建完成了。


三、module 名称应该怎么写?

学习阶段可以直接使用:

1go mod init hello-go
2

对应:

1module hello-go
2

但是在真实项目尤其是准备上传 GitHub 的项目中,更常见的是使用仓库地址作为模块路径。

例如项目地址假设为:

1github.com/zhangsan/go-shop
2

初始化:

1go mod init github.com/zhangsan/go-shop
2

生成:

1module github.com/zhangsan/go-shop
2

之后项目内部引用自己的包时,就可以使用:

1import "github.com/zhangsan/go-shop/service"
2

因此实际开发中,模块路径通常与代码仓库路径保持一致。


四、安装第一个第三方依赖

下面以 Gin 为例。

创建 main.go:

1package main
2
3import "github.com/gin-gonic/gin"
4
5func main() {
6	r := gin.Default()
7
8	r.GET("/", func(c *gin.Context) {
9		c.String(200, "Hello Go Modules")
10	})
11
12	r.Run(":8080")
13}
14

此时项目使用了:

1github.com/gin-gonic/gin
2

可以执行:

1go get github.com/gin-gonic/gin
2

Go 会自动下载 Gin 以及它需要的相关依赖。

再次打开 go.mod,会看到相应依赖信息。


五、require 是什么?

安装依赖以后,go.mod 中可能出现:

1require github.com/gin-gonic/gin v1.x.x
2

require 表示当前项目依赖某个模块。

基本格式:

1require 模块路径 版本号
2

例如:

1require github.com/gin-gonic/gin v1.x.x
2

表示:

当前项目需要 Gin,并使用指定版本。

如果有多个依赖,通常会写成:

1require (
2	github.com/gin-gonic/gin v1.x.x
3	github.com/go-redis/redis/v9 v9.x.x
4)
5

因此,通过 go.mod,我们可以非常清楚地知道一个项目需要哪些依赖。


六、直接依赖与间接依赖

打开实际项目中的 go.mod,经常会看到:

1require (
2	github.com/gin-gonic/gin v1.x.x
3	example.com/some-package v1.x.x // indirect
4)
5

这里的:

1// indirect
2

表示间接依赖。

假设我们的项目依赖 Gin:

1我们的项目
2    ↓
3Gin
4    ↓
5其他第三方库
6

我们直接使用 Gin,因此 Gin 属于直接依赖。

Gin 自身又需要其他库,而我们的代码没有直接使用这些库,它们就是间接依赖。

可以理解为:

1项目 → Gin → A → B
2

其中 Gin 是直接依赖,而 A、B 可能属于间接依赖。

Go Modules 会自动维护这些关系。


七、go.sum 是什么?

安装第三方依赖后,项目中通常还会出现:

1go.sum
2

于是项目结构可能变为:

1go-module-demo
2├── go.mod
3├── go.sum
4└── main.go
5

go.sum 中会出现很多类似记录:

1github.com/xxx/xxx v1.2.3 h1:xxxx
2github.com/xxx/xxx v1.2.3/go.mod h1:xxxx
3

它并不是另一个依赖列表,而主要记录模块版本相关内容的校验值。

它的作用之一就是帮助 Go 验证下载到的依赖内容是否与此前记录的一致。

因此实际项目中:

1go.mod
2go.sum
3

通常都应该提交到 Git 仓库。

不要因为 go.sum 看起来很长就随意删除它。


八、go get 的作用

go get 主要用于调整当前模块的依赖。

例如添加:

1go get github.com/gin-gonic/gin
2

如果需要指定版本,可以使用:

1go get github.com/gin-gonic/gin@v1.x.x
2

升级到符合要求的新版本时,也可以通过指定版本进行调整。

例如:

1go get example.com/library.5.0
2

执行之后,Go 会根据依赖关系更新:

1go.mod
2go.sum
3

实际项目中,推荐明确关注依赖版本变化,而不是看到升级提示就全部更新。


九、go mod tidy 非常重要

开发 Go 项目时,非常常用的一条命令是:

1go mod tidy
2

它主要用于整理当前模块依赖。

例如代码中新增:

1import "github.com/gin-gonic/gin"
2

执行:

1go mod tidy
2

Go 会根据源码中实际使用的包补充所需模块信息。

反过来,如果你删除了某些代码,不再需要某个依赖,go mod tidy 也会清理不再需要的依赖记录。

因此可以简单理解为:

1go mod tidy
2

就是让 go.mod 和 go.sum 与当前代码真正需要的依赖保持一致。

开发过程中建议经常执行。


十、常用 go mod 命令

查看 go mod 支持的功能:

1go help mod
2

初始化模块:

1go mod init 项目名称
2

整理依赖:

1go mod tidy
2

下载当前模块所需依赖:

1go mod download
2

查看模块依赖关系:

1go list -m all
2

检查模块依赖:

1go mod verify
2

如果想查看模块依赖图,可以执行:

1go mod graph
2

这些命令在以后分析大型项目依赖时非常有用。


十一、依赖下载到哪里?

很多初学者会问:

执行:

1go get
2

之后,源码到底下载到哪里了?

可以执行:

1go env GOPATH
2

然后查看:

1GOPATH/pkg/mod
2

例如 macOS:

1/Users/用户名/go/pkg/mod
2

Linux:

1/home/用户名/go/pkg/mod
2

Windows:

1C:\Users\用户名\go\pkg\mod
2

这里就是 Go 的模块缓存目录。

还可以执行:

1go env GOMODCACHE
2

直接查看当前模块缓存路径。

通常不需要手动修改里面的文件,因为这些内容由 Go 工具链管理。


十二、什么是 GOPROXY?

Go 下载第三方模块时,可以通过模块代理访问依赖。

查看当前配置:

1go env GOPROXY
2

常见配置形式:

1https://proxy.golang.org,direct
2

其中:

1direct
2

表示代理无法获取模块时,可以尝试直接访问源码仓库。

如果当前网络环境访问默认代理不方便,也可以配置其他可用代理,例如:

1go env -w GOPROXY=https://goproxy.cn,direct
2

配置完成后查看:

1go env GOPROXY
2

需要注意,代理属于开发环境配置,并不是一定要写到项目源码中的内容。


十三、版本号是什么意思?

Go 模块通常使用语义化版本号。

例如:

1v1.5.2
2

可以拆分为:

1v 主版本.次版本.修订版本
2

也就是:

1v1.5.2
2 │ │ │
3 │ │ └── 修订版本
4 │ └──── 次版本
5 └────── 主版本
6

通常:

  • 修订版本用于错误修复;
  • 次版本增加向后兼容的新功能;
  • 主版本可能包含不兼容变化。

因此大型项目中,升级依赖前应阅读相应项目的更新说明,并通过测试确认兼容性。


十四、不要手动乱改 go.mod

虽然 go.mod 是文本文件,可以直接编辑,但初学阶段不建议随意修改依赖版本。

例如直接将:

1v1.5.0
2

改成:

1v99.0.0
2

如果这个版本根本不存在,项目自然无法正确下载依赖。

通常应该使用:

1go get 模块@版本
2

或者:

1go mod tidy
2

让 Go 工具链帮助管理依赖关系。


十五、一个完整的依赖管理流程

假设我们创建一个 Gin 项目。

第一步:

1mkdir gin-demo
2cd gin-demo
3

第二步:

1go mod init gin-demo
2

第三步,在代码中引用:

1import "github.com/gin-gonic/gin"
2

第四步:

1go mod tidy
2

Go 会下载代码需要的依赖。

第五步运行:

1go run .
2

如果将项目上传 Git,一般提交:

1main.go
2go.mod
3go.sum
4

其他开发者下载项目后,可以执行:

1go mod download
2

或者直接:

1go build
2

Go 会根据模块信息获取所需依赖。

这就是 Go Modules 最核心的价值之一:让不同开发环境能够按照明确的模块依赖构建项目。


十六、本章小结

Go Modules 是现代 Go 项目最重要的基础知识之一。

本篇主要介绍了:

  • 什么是 Go Modules
  • 使用 go mod init 初始化模块
  • go.mod 的作用
  • module 模块路径
  • require 依赖声明
  • 直接依赖与间接依赖
  • go.sum 的作用
  • 使用 go get 调整依赖
  • 使用 go mod tidy 整理依赖
  • 使用 GOPROXY 下载模块
  • 模块缓存的位置
  • 依赖版本的基本规则

以后无论使用 Gin、GORM、Redis、gRPC 还是其他 Go 第三方库,都需要和 Go Modules 打交道。

因此建议重点掌握这几个命令:

1go mod init
2go get
3go mod tidy
4go mod download
5go list -m all
6

掌握 Go Modules 后,我们就能够更加规范地创建和管理真实的 Go 项目。


本章练习

  1. 创建一个 module-demo 项目。
  2. 使用 go mod init module-demo 初始化模块。
  3. 安装一个第三方 Go 库。
  4. 查看 go.mod 中发生了什么变化。
  5. 查看生成的 go.sum。
  6. 执行 go mod tidy 整理依赖。
  7. 使用 go list -m all 查看依赖列表。
  8. 使用 go env GOMODCACHE 找到模块缓存目录。

下一篇预告

《GOPATH 与 Go Modules 的区别》

学习 Go 时,经常会在旧教程中看到:

1GOPATH/src
2GOPATH/pkg
3GOPATH/bin
4

而新的 Go 项目却通常直接使用:

1go.mod
2go.sum
3

那么 GOPATH 到底是什么?为什么以前项目必须放在 GOPATH 中,而现在可以放在任意目录?已经有 Go Modules 以后,GOPATH 还有没有作用?

下一篇将详细介绍 GOPATH 与 Go Modules 的发展过程、目录结构、依赖管理方式、项目组织方式以及两者之间的核心区别,帮助大家彻底解决学习 Go 时经常遇到的 GOPATH 与 Modules 混淆问题。


《Go Modules 包管理详解:go.mod、go.sum 与依赖管理》 是转载文章,点击查看原文。


相关推荐


Alibaba买家账号运营指南:注册流程、账号养护及多账号管理实践
xiaobaihuoke2026/7/18

在跨境电商行业中,很多企业把重点放在卖家账号运营、产品推广以及广告投放上,但实际上,一个稳定、高质量的买家账号,同样是跨境运营体系中不可忽视的重要资源。 无论是进行海外市场调研、寻找供应商、分析行业趋势,还是获取产品报价,一个真实、活跃的Alibaba国际站买家号,都能够帮助企业更加深入了解市场。 然而,随着Alibaba平台风控机制不断完善,买家账号的运营已经不再是简单注册即可使用。账号注册后的行为习惯、活跃程度以及采购轨迹,都会影响账号后续的使用价值。 因此,买家号运营逐渐形成了一个完


再见Fable 5,OpenAI出手了!GPT-5.6真香~
AI袋鼠帝2026/7/10

大家好,我是袋鼠帝 我最近在疯狂使用Fable 5,好用是好用,就是太贵啦! 不过不是在Claude 官方使用的,因为我最新的一个号,在7月1号又tm被封了,服了都(已经记不清是第几个了) 天下苦A社久矣.. 所以,我最近都是在Cursor上用的Fable 5,虽然我下血本充了200$的订阅,但跑了两天Fable 5,总用量就已经超过48%了。。。 整的我都有点不敢用了,除非核心任务,其他时候我都只敢开启auto模式(自动选择模型) 就是这么憋屈。 然后今天凌晨,OpenAI终于出手了! G


从零构建ReAct智能体:让AI学会边想边做
树獭非懒2026/7/2

前言 大语言模型已经能写诗、编程、做数学题,但它有一个根本性的短板:无法与外部世界交互。你问它"今天深圳天气怎么样",它只能诚恳地告诉你"我的知识截止到某某日期"——不是它不想回答,是它根本没有"看天气"这个动作能力。 这就是智能体(Agent)要解决的核心问题:让 LLM 不仅能想,还能做。 业界现有的智能体框架(LangChain、LlamaIndex 等)已经将这套机制封装得非常完善,但它们的高度抽象也让很多人停留在"调包侠"阶段,对背后的运行机制一知半解。本文的目标,是带你从零构建一个


Swift 还让你 Excited 吗?-- 肘子的 Swift 周报 #141
东坡肘子2026/6/23

Swift 还让你 Excited 吗? 上周,Reddit 上一篇题为《Is anyone else excited by Swift progress as the language?》的帖子引发了不少讨论。WWDC 2026 上,Apple 明确表示,Swift 已被用于 WebKit 关键组件、QUIC 网络栈、字体渲染、驱动与固件。发帖者据此认为,Swift 正在向核心操作系统内核迈进,并将这一幕视为 2014 年"高级系统编程语言"承诺的兑现。评论区的讨论则很快从“是否兑现了承诺”,


别再让业务层裸奔 CarPropertyManager 了!谈谈汽车车载核心服务的架构封装
潜龙勿用之化骨龙2026/6/15

前言 Android Automotive 项目中,CarPropertyManager 几乎是访问一切车辆状态的入口。但在真实项目里,如果直接在 ViewModel 或业务层大量使用它,代码会变得难以维护、难以测试,也完全不符合 现代Android 架构 的分层思想。 本文将从零开始,梳理一套基于 Clean Architecture 的 CarPropertyManager 封装方案,涵盖: 为什么不能直接用 如何用抽象基类统一封装 callbackFlow 的正确姿势 Flow 与 su


「装闭」-AI驱动的开源装修闭坑系统
fthux2026/6/8

愿每个业主在装修路上心中有数,于是,「装闭」来了。 装修行业的水有点儿深 很多人装修完回头看,都发现自己花了不少冤枉钱。设计师画的效果图美轮美奂——复杂吊顶、满墙背景墙、开放格书架……装好以后才发现,这些东西费钱不说,日常打理还特别费劲。吊顶积灰、开放格藏污纳垢、花哨灯带一年到头开不了几次。 更别说合同和报价单里的猫腻。增项漏项、模糊工艺描述、虚报材料数量——这些套路装修公司玩得轻车熟路,但普通业主根本无从分辨。随便一个增项,几千块甚至上万块就多出来了。 于是就有了「装闭」(RenoPit)这


译 · Jake Wharton 访谈:Android 圈最熟悉的那个名字
bqliang2026/6/1

Jake Wharton 是我的偶像,也是很多 Android 开发者绕不开的名字。Retrofit、OkHttp、Dagger、Ktx... 这些项目或多或少都影响过我们写 Android 的方式。 前几天在网上看到他的这篇访谈,读完觉得很受用。里面既有他早年做 Android、做开源的经历,也有他对职业选择、会议、倦怠、家庭和工作方式的很多真实想法。这里把它翻译成中文,分享给同样喜欢 Android、Kotlin 和开源的朋友们。 ⚡️ 欢迎来到 Effective Interviews


从 textarea 到 AI 输入框:用 Tiptap 实现 / 命令、@ 引用和结构化请求
倾颜2026/5/11

本文对应项目版本:v0.0.12 在一个 AI 应用刚开始做聊天功能时,textarea 往往已经够用了。 用户输入一段自然语言,前端把它发给后端,后端拿到消息数组,模型开始生成回答。这个链路简单、直接,也足够支撑最早期的问答场景。 但当项目里慢慢出现 Skill(任务能力层)、Tool(可执行工具)、Resource(可读取上下文)、Prompt(可注入模型的提示模板)、MCP 能力(通过 MCP 接入的外部能力)之后,我开始遇到一个更具体的问题:用户输入不再只是一段自然语言。 它开始同时表


解决 4 大 AI 编码痛点:Matt Pocock 的 Skill 工作流深度拆解
小碗细面 VIP.5 如鱼得水2026/5/1

解决 4 大 AI 编码痛点:Matt Pocock 的 Skill 工作流深度拆解 当所有人都在用 AI 写更多代码的时候,TypeScript 之神 Matt Pocock 把自己的 .claude 目录直接推到 GitHub 上,告诉我们:先别急着 vibe coding,把工程基本功捡回来。 一、写在前面:一个让人拍大腿的开源项目 2026 年 3 月,TypeScript 社区的"老熟人"Matt Pocock(你大概率在他的 Total TypeScript 课程下面留过言)干了


Android Studio 项目模板完全指南
90后晨仔2026/4/22

本文将详细介绍 Android Studio 中创建项目时的各种模板选项,帮助你快速选择最适合的项目起点。一个小白的自学成长之路 一、设备类型分类 首先,左侧列表显示了不同的设备平台: Phone and Tablet:手机和平板应用(最常用) Wear OS:智能手表应用 Android TV:电视应用 Automotive:车载应用 二、Phone and Tablet 模板详解 1. No Activity 含义:创建一个没有任何活动(Activity)的空项目

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 聚合阅读