go.mod 文件参考
每个 Go 模块都由一个 go.mod 文件定义,该文件描述了模块的属性,包括它对其他模块和 Go 版本的依赖关系。
这些属性包括
- 当前模块的 模块路径。这应该是一个 Go 工具可以下载模块的位置,例如模块代码的仓库位置。它与模块的版本号结合使用时,可作为唯一的标识符。它也是模块中所有包的包路径前缀。有关 Go 如何找到模块的更多信息,请参阅 Go 模块参考。
- 当前模块所需的最低 Go 版本。
- 当前模块所需的其他 模块 的最低版本列表。
- 可选地,指示如何用另一个模块版本或本地目录 替换 所需模块,或者 排除 所需模块的特定版本。
运行 go mod init
命令 时,Go 会生成一个 go.mod 文件。以下示例创建一个 go.mod 文件,将模块路径设置为 example/mymodule
$ go mod init example/mymodule
使用 go
命令来管理依赖项。这些命令确保 go.mod 文件中描述的需求保持一致,并且 go.mod 文件的内容有效。这些命令包括 go get
、 go mod tidy
和 go mod edit
命令。
有关 go
命令的参考,请参阅 Command go。您可以通过命令行输入 go help
command-name 来获取帮助,例如 go help mod tidy
。
另请参阅
示例
go.mod 文件包含如下例所示的指令。本文档的其他地方描述了这些指令。
module example.com/mymodule
go 1.14
require (
example.com/othermodule v1.2.3
example.com/thismodule v1.2.3
example.com/thatmodule v1.2.3
)
replace example.com/thatmodule => ../thatmodule
exclude example.com/thismodule v1.3.0
module
声明模块的模块路径,该路径是模块的唯一标识符(与模块版本号结合使用时)。模块路径成为模块中所有包的导入前缀。
更多信息,请参阅 Go 模块参考中的 module
指令。
语法
module module-path
- 模块路径 (module-path)
- 模块的模块路径,通常是 Go 工具可以下载模块的仓库位置。对于 v2 及更高版本的模块,此值必须以主要版本号结尾,例如
/v2
。
示例
以下示例将 example.com
替换为可以下载模块的仓库域名。
- v0 或 v1 模块的模块声明
module example.com/mymodule
- v2 模块的模块路径
module example.com/mymodule/v2
注意事项
模块路径必须唯一标识您的模块。对于大多数模块,该路径是 go
命令可以找到代码的 URL(或代码的重定向地址)。对于永远不会直接下载的模块,模块路径可以只是您控制的某个名称,以确保唯一性。前缀 example/
也保留用于此类示例。
更多详情,请参阅 管理依赖项。
在实践中,模块路径通常是模块源的仓库域名以及仓库中模块代码的路径。当下载模块版本以代表模块用户解决依赖关系时,go
命令依赖于此形式。
即使您最初不打算让您的模块可供其他代码使用,使用其仓库路径也是一种最佳实践,可以帮助您在以后发布模块时避免重命名。
如果您最初不知道模块最终的仓库位置,可以考虑暂时使用一个安全的替代品,例如您拥有的域名或您控制的名称(例如您的公司名称),以及模块名称或源目录的路径。更多信息,请参阅 管理依赖项。
例如,如果您正在 stringtools
目录中开发,您的临时模块路径可能是 <company-name>/stringtools
,如下例所示,其中 company-name 是您公司的名称
go mod init <company-name>/stringtools
go
指示模块是根据指令指定的 Go 版本的语义编写的。
更多信息,请参阅 Go 模块参考中的 go
指令。
语法
go minimum-go-version
- 最低 Go 版本 (minimum-go-version)
- 编译此模块中包所需的最低 Go 版本。
示例
- 模块必须在 Go 1.14 或更高版本上运行
go 1.14
注意事项
go
指令设置了使用此模块所需的最低 Go 版本。在 Go 1.21 之前,该指令仅为建议性;现在它是一项强制要求:Go 工具链拒绝使用声明了更新 Go 版本的模块。
go
指令是选择要运行哪个 Go 工具链的输入。有关详细信息,请参阅“Go 工具链”。
go
指令影响新语言特性的使用
- 对于模块中的包,编译器会拒绝使用在
go
指令指定的版本之后引入的语言特性。例如,如果一个模块具有go 1.12
指令,其包不能使用像1_000_000
这样的数字文字,这些特性是在 Go 1.13 中引入的。 - 如果旧版 Go 构建了模块中的某个包并遇到编译错误,则错误会指出该模块是为较新版本 Go 编写的。例如,假设一个模块具有
go 1.13
,并且一个包使用了数字文字1_000_000
。如果使用 Go 1.12 构建该包,编译器会指出代码是为 Go 1.13 编写的。
go
指令也影响 go
命令的行为
- 在
go 1.14
或更高版本中,可能会启用自动 vendoring(供应商)。如果文件vendor/modules.txt
存在且与go.mod
一致,则无需显式使用-mod=vendor
标志。 - 在
go 1.16
或更高版本中,all
包模式仅匹配 主模块 中的包和测试间接导入的包。这与自从引入模块以来go mod vendor
保留的包集相同。在较低版本中,all
还包括主模块中包导入的包的测试、这些包的测试等等。 - 在
go 1.17
或更高版本中go.mod
文件为每个提供主模块中包或测试间接导入的任何包的模块包含一个显式的require
指令。(在go 1.16
及更低版本中,仅当 最小版本选择 否则会选择不同版本时才包含间接依赖项。)此附加信息使得 模块图修剪 和 惰性模块加载 成为可能。- 由于
// indirect
依赖项可能比以前的go
版本多得多,因此间接依赖项记录在go.mod
文件中的一个单独块中。 go mod vendor
会省略供应商依赖项的go.mod
和go.sum
文件。(这允许在vendor
子目录中调用go
命令时识别正确的主模块。)go mod vendor
在vendor/modules.txt
文件中记录每个依赖项的go.mod
文件中的go
版本。
- 在
go 1.21
或更高版本中go
行声明了使用此模块所需的最低 Go 版本。go
行必须大于或等于所有依赖项的go
行。go
命令不再尝试保持与先前旧版 Go 的兼容性。go
命令更谨慎地在go.sum
文件中保留go.mod
文件的校验和。
一个 go.mod
文件最多只能包含一个 go
指令。如果不存在 go
指令,大多数命令会添加一个当前 Go 版本的 go
指令。
toolchain
声明与此模块一起使用的建议 Go 工具链。仅当模块是主模块且默认工具链早于建议的工具链时才生效。
更多信息请参阅“Go 工具链”和 Go 模块参考中的 toolchain
指令。
语法
toolchain toolchain-name
- toolchain 名称 (toolchain-name)
- 建议的 Go 工具链名称。标准工具链名称采用
goV
形式,其中 V 是 Go 版本,例如go1.21.0
和go1.18rc1
。特殊值default
禁用自动工具链切换。
示例
- 建议使用 Go 1.21.0 或更高版本
toolchain go1.21.0
注意事项
有关 toolchain
行如何影响 Go 工具链选择的详细信息,请参阅“Go 工具链”。
godebug
指示应用于此模块主包的默认 GODEBUG 设置。这些设置会覆盖任何工具链默认设置,并被主包中显式的 //go:debug
行覆盖。
语法
godebug debug-key=debug-value
- debug 键 (debug-key)
- 要应用的设置名称。可以在 GODEBUG 历史 中找到设置列表及其引入版本。
- debug 值 (debug-value)
- 为设置提供的值。如果没有另外指定,
0
表示禁用,1
表示启用指定的行为。
示例
- 使用 Go 1.23 新的
asynctimerchan=0
行为godebug asynctimerchan=0
- 使用 Go 1.21 的默认 GODEBUG,但采用旧的
panicnil=1
行为godebug ( default=go1.21 panicnil=1 )
注意事项
GODEBUG 设置仅应用于当前模块中主包和测试二进制文件的构建。当模块作为依赖项使用时,它们不起作用。
有关向后兼容性的详细信息,请参阅“Go、向后兼容性和 GODEBUG”。
require
将模块声明为当前模块的依赖项,并指定所需模块的最低版本。
更多信息,请参阅 Go 模块参考中的 require
指令。
语法
require module-path module-version
- 模块路径 (module-path)
- 模块的模块路径,通常是模块源的仓库域名和模块名称的连接。对于 v2 及更高版本的模块,此值必须以主要版本号结尾,例如
/v2
。 - 模块版本 (module-version)
- 模块的版本。这可以是发布版本号,例如 v1.2.3,也可以是 Go 生成的伪版本号,例如 v0.0.0-20200921210052-fa0125251cc4。
示例
- 依赖已发布版本 v1.2.3
require example.com/othermodule v1.2.3
- 通过使用 Go 工具生成的伪版本号来依赖仓库中尚未打标签的版本
require example.com/othermodule v0.0.0-20200921210052-fa0125251cc4
注意事项
当您运行 go get
等 go
命令时,Go 会为每个包含导入包的模块插入 require
指令。当模块在仓库中尚未打标签时,Go 会在您运行命令时为其分配一个生成的伪版本号。
您可以使用 replace
指令 让 Go 从非其仓库的位置依赖模块。
更多关于版本号的信息,请参阅 模块版本号。
更多关于管理依赖项的信息,请参阅以下内容
tool
将包添加为当前模块的依赖项,并在当前工作目录在此模块内时使其可用以使用 go tool
运行。
语法
tool package-path
- 包路径 (package-path)
- 工具的包路径,它是包含该工具的模块以及模块内实现该工具的包路径(可能为空)的连接。
示例
- 声明当前模块中实现的工具
module example.com/mymodule tool example.com/mymodule/cmd/mytool
- 声明在单独模块中实现的工具
module example.com/mymodule tool example.com/atool/cmd/atool require example.com/atool v1.2.3
注意事项
您可以使用 go tool
通过完全限定的包路径运行在您的模块中声明的工具,或者在没有歧义的情况下,通过最后一个路径段运行。在上面的第一个示例中,您可以运行 go tool mytool
或 go tool example.com/mymodule/cmd/mytool
。
在工作区模式下,您可以使用 go tool
运行任何工作区模块中声明的工具。
工具使用与模块本身相同的模块图构建。需要一个 require
指令 来选择实现该工具的模块版本。任何 replace
指令 或 exclude
指令 也适用于该工具及其依赖项。
更多信息请参阅 工具依赖项。
replace
用另一个模块版本或本地目录替换特定版本(或所有版本)的模块内容。Go 工具在解析依赖项时将使用替换路径。
更多信息,请参阅 Go 模块参考中的 replace
指令。
语法
replace module-path [module-version] => replacement-path [replacement-version]
- 模块路径 (module-path)
- 要替换的模块的模块路径。
- 模块版本 (module-version)
- 可选。要替换的特定版本。如果省略此版本号,则该模块的所有版本都将被箭头右侧的内容替换。
- 替换路径 (replacement-path)
- Go 应该查找所需模块的路径。这可以是一个模块路径,也可以是替换模块本地文件系统上的目录路径。如果这是模块路径,您必须指定一个 replacement-version 值。如果这是本地路径,则不能使用 replacement-version 值。
- 替换版本 (replacement-version)
- 替换模块的版本。仅当 replacement-path 是模块路径(而不是本地目录)时才能指定替换版本。
示例
-
用模块仓库的分支替换
在以下示例中,example.com/othermodule 的任何版本都被其代码的指定分支替换。
require example.com/othermodule v1.2.3 replace example.com/othermodule => example.com/myfork/othermodule v1.2.3-fixed
当您用另一个模块路径替换一个模块路径时,请不要更改您正在替换的模块中包的导入语句。
更多关于使用模块代码分支副本的信息,请参阅 从您自己的仓库分支依赖外部模块代码。
-
用不同的版本号替换
以下示例指定应使用版本 v1.2.3,而不是该模块的任何其他版本。
require example.com/othermodule v1.2.2 replace example.com/othermodule => example.com/othermodule v1.2.3
以下示例用同一模块的 v1.2.3 版本替换模块版本 v1.2.5。
replace example.com/othermodule v1.2.5 => example.com/othermodule v1.2.3
-
用本地代码替换
以下示例指定应使用本地目录作为该模块所有版本的替换。
require example.com/othermodule v1.2.3 replace example.com/othermodule => ../othermodule
以下示例指定应使用本地目录仅作为 v1.2.5 的替换。
require example.com/othermodule v1.2.5 replace example.com/othermodule v1.2.5 => ../othermodule
更多关于使用模块代码本地副本的信息,请参阅 依赖本地目录中的模块代码。
注意事项
当您希望 Go 使用另一个路径查找模块的源时,使用 replace
指令可以暂时用另一个值替换模块路径值。这实际上是将 Go 对模块的搜索重定向到替换位置。您无需更改包导入路径即可使用替换路径。
构建当前模块时,使用 exclude
和 replace
指令控制构建时依赖项解析。这些指令在依赖于当前模块的模块中会被忽略。
replace
指令在以下情况中非常有用
- 您正在开发一个新模块,其代码尚未入库。您想使用本地版本进行客户端测试。
- 您已经发现依赖项存在问题,并克隆了依赖项的仓库,然后正在使用本地仓库测试修复。
请注意,仅靠 replace
指令不会将模块添加到 模块图。还需要一个引用被替换模块版本的 require
指令,可以在主模块的 go.mod
文件中,也可以在依赖项的 go.mod
文件中。如果您没有要替换的特定版本,可以使用一个虚假版本,如下例所示。请注意,这将破坏依赖您的模块的模块,因为 replace
指令仅在主模块中应用。
require example.com/mod v0.0.0-replace
replace example.com/mod v0.0.0-replace => ./mod
更多关于替换所需模块的信息,包括使用 Go 工具进行更改,请参阅
更多关于版本号的信息,请参阅 模块版本号。
exclude
指定要从当前模块的依赖图排除的模块或模块版本。
更多信息,请参阅 Go 模块参考中的 exclude
指令。
语法
exclude module-path module-version
- 模块路径 (module-path)
- 要排除的模块的模块路径。
- 模块版本 (module-version)
- 要排除的特定版本。
示例
-
排除 example.com/theirmodule 的 v1.3.0 版本
exclude example.com/theirmodule v1.3.0
注意事项
使用 exclude
指令排除间接依赖但由于某种原因无法加载的模块的特定版本。例如,您可以使用它排除校验和无效的模块版本。
构建当前模块(您正在构建的主模块)时,使用 exclude
和 replace
指令控制构建时依赖项解析。这些指令在依赖于当前模块的模块中会被忽略。
您可以使用 go mod edit
命令排除模块,如下例所示。
go mod edit -exclude=example.com/theirmodule@v1.3.0
更多关于版本号的信息,请参阅 模块版本号。
retract
指示由 go.mod
定义的模块的某个版本或某个版本范围不应被依赖。当版本过早发布或发布后发现了严重问题时,retract
指令很有用。
更多信息,请参阅 Go 模块参考中的 retract
指令。
语法
retract version // rationale retract [version-low,version-high] // rationale
- 版本 (version)
- 要撤回的单个版本。
- 版本下限 (version-low)
- 要撤回的版本范围的下限。
- 版本上限 (version-high)
- 要撤回的版本范围的上限。范围包含 version-low 和 version-high。
- 理由 (rationale)
- 解释撤回原因的可选注释。可能会在发送给用户的消息中显示。
示例
-
撤回单个版本
retract v1.1.0 // Published accidentally.
-
撤回一系列版本
retract [v1.0.0,v1.0.5] // Build broken on some platforms.
注意事项
使用 retract
指令表示您的模块的先前版本不应被使用。用户不会通过 go get
、go mod tidy
或其他命令自动升级到被撤回的版本。用户不会看到被撤回的版本作为 go list -m -u
的可用更新。
撤回的版本应该保持可用,以便已经依赖它们的用户能够构建他们的包。即使撤回的版本从源仓库中删除,它仍可能在 proxy.golang.org 等镜像上可用。依赖撤回版本的用户在对相关模块运行 go get
或 go list -m -u
时可能会收到通知。
go
命令通过读取模块最新版本中 go.mod
文件中的 retract
指令来发现撤回的版本。最新版本按优先级顺序为
- 其最高的发布版本(如果有)
- 其最高的预发布版本(如果有)
- 仓库默认分支尖端的伪版本。
当您添加撤回时,几乎总是需要打一个新的、更高的版本标签,以便命令在模块的最新版本中看到它。
您可以发布一个其唯一目的是表明撤回的版本。在这种情况下,新版本也可以撤回自身。
例如,如果您不小心打上了 v1.0.0
的标签,您可以打上 v1.0.1
的标签,并包含以下指令
retract v1.0.0 // Published accidentally.
retract v1.0.1 // Contains retraction only.
不幸的是,一旦版本发布,就无法更改。如果您之后在不同的提交上打上 v1.0.0
的标签,go
命令可能会在 go.sum
或 校验和数据库 中检测到校验和不匹配。
撤回的模块版本通常不会出现在 go list -m -versions
的输出中,但您可以使用 -retracted
来显示它们。更多信息,请参阅 Go 模块参考中的 go list -m
。