如果你时常关注 Go 的最新新闻,那么一定会知道 go1.11
中终于实现了 go module
,终于可以使用官方推荐的模块化编程方案了
本文, 我们就一窥 go module
的全貌,看看它到底是何方神圣,有何齐天的本事
go module 定义
模块 ( module
) 是相关 go
包的集合,是是源代码交换 ( interchange
) 和版本化控制的基本单元
简史
1.5
版本之前的go
,go get
命令会将包会下载到GOPATH
路径中1.5
及以上版本,添加了 依赖的组织名- vgo 被提议作为 Go 模块支持的原型
- Go 1.11 (beta) 版本中,
vgo
被合并到主干代码并改进为go mod
( 实验性质 )
术语
本文重复引用了一些表达式,我们将它们罗列于此
- 「模块根目录」 ( Module root ) : 包含了名为
go.mod
文件的目录 - 「模块路径」 ( Module path ) : 与模块根目录对应的导入路径的前缀
- 「主模块」( Main module ) : 包行了运行 go 命令的所在目录的模块
模块结构
模块是包含了 Go 源文件的目录树,并在根目录中添加了名为 go.mod
的文件
go.mod
包含模块导入名称,声明了要求的依赖项,排除的依赖项和替换的依赖项
下面的代码就是一个简化了的 go.mod
的内容
module my/thing require ( one/thing v1.3.2 other/thing v2.5.0 // indirect ... ) exclude ( bad/thing v0.7.3 ) replace ( src/thing 1.0.2 => dst/thing v1.1.0 )
需要注意的是,该文件中声明的依赖,并不会在模块的源代码中使用 import
自动导入,还是需要我们人工添加 import
语句来导入的
模块可以包含其他模块,在这种情况下,它们的内容将从父模块中排除
除了 go.mod
文件外,跟目录下还可以存在一个名为 go.sum
的文件,用于保存所有的依赖项的哈希摘要校验之,用于验证缓存的依赖项是否满足模块要求
「 模块根目录 」可以存放于文件系统上的任何为止,而不用管 GOPATH
路径到底是什么
模块的依赖项
模块依赖项会被下载并存储到 GOPATH/src/mod
目录中,直接后果就是废除了模块的组织名称
那么,新的结构到底是什么样的呢?假设我们正在开发的项目依赖于 github.com/me/lib
且版本号 1.0.0
的模块,对于这种情况,我们会发现在 GOPATH/src/mod
中文件结构如下
从上面这张图中我们可以看到
- 依赖项的源代码文件结构保存在此目录的根目录,并做了一些细微改动:导入路径以
@version
为后缀 - 从 VCS 中获取或构建的源归档文件放置在
download
目录中 - VCS 数据保存在
vcs
目录中
开启 go module 支持
在 Go 1.11beta2
中,可以通过设置环境变量 GO111MODULE
控制是启用还是禁用模块支持。它接受三个值:on
,off
,auto
( 默认 )
- 如果设置为
on
,那么无论模块在于何种路径,都会启用模块支持 - 如果设置为
off
,则永远禁用 go module 支持 - 如果没有设置,或设置为
auto
,开启支持模块功能,但如果模块路径位于GOPATH
路径之外,则需要当前目录是模块根目录或其子目录之一
集成
go module 功能被集成到 go
命令行工具中,例如,在调用诸如 go build
,go install
,go run
,go test
之类的命令时,将启动相应的操作,如缓存,创建或更新 go.mod
和 go.sum
等
自动格式化
我们永远不必自己运行这些命令 ( 格式化命令 ),因为它们是由其他命令调用的
但是为了完整起见,我们顺带提一下 ,对于 go.mod
和 go.sum
文件而言, go mod -fmt
相当于 go fmt
,并且 go mod -fix
做了一些聪明的事情以保持 go.mod
清洁,例如
- 将非规范版本标识符重写为语义版本控制形式
- 删除重复项
- 更新依赖,排除非依赖
后记
因为篇幅有限,本章节我们就讲到这里。本章节中,我们讲解了一些 go module 的基础知识,但我们还没有开始开发自己的模块
那么,下一章节,我们就来开发一个自己的模块的吧
#1 • 5 年, 6 月 前 •
在使用GOMODULE时往往会出现Internal Server Error或Timeout等问题。 GOPROXY能够在一定程度上解决在拉取诸如 golang.org/x 包的时候产生的超时问题,也可以在一定程度上解决由于项目改名、迁移、删除等原因导致的404问题。 但是需要注意的是,使用GOPROXY将导致你无法拉取私有储存库。 现在,GOS解决了这个问题。 https://github.com/storyicon/gos