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(或重定向到代码的 URL)。对于永远不会直接下载的模块,模块路径可以是您控制的某个名称,以确保唯一性。前缀 example/ 也保留用于此类示例。
有关更多详细信息,请参阅管理依赖项。
实际上,模块路径通常是模块源的仓库域和仓库内模块代码的路径。go 命令在下载模块版本以代表模块用户解决依赖项时依赖此形式。
即使您最初不打算使您的模块可用于其他代码,使用其仓库路径也是一种最佳实践,它将帮助您避免在以后发布模块时不得不重命名模块。
如果您最初不知道模块的最终仓库位置,请考虑暂时使用安全的替代方案,例如您拥有的域名或您控制的名称(例如您的公司名称),以及模块名称或源目录的路径。有关更多信息,请参阅管理依赖项。
例如,如果您正在 stringtools 目录中开发,您的临时模块路径可能是 <company-name>/stringtools,如下例所示,其中 company-name 是您的公司名称
go mod init <company-name>/stringtools
go
指示模块是假设指令指定的 Go 版本的语义编写的。
有关更多信息,请参阅 Go 模块参考中的go 指令。
语法
go minimum-go-version
- 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及更低版本中,只有当最小版本选择会选择不同版本时,才包含间接依赖项。)此额外信息支持模块图修剪和惰性模块加载。- 由于间接依赖项可能比以前的
go版本多得多,因此间接依赖项记录在go.mod文件中的单独块中。 go mod vendor省略了 vendored 依赖项的go.mod和go.sum文件。(这允许在vendor的子目录中调用go命令来识别正确的主模块。)go mod vendor将每个依赖项的go.mod文件中的go版本记录在vendor/modules.txt中。
- 在
go 1.21或更高版本中go行声明了与此模块一起使用的最低 Go 版本要求。go行必须大于或等于所有依赖项的go行。go命令不再尝试与旧版 Go 保持兼容性。go命令在go.sum文件中保留go.mod文件的校验和方面更加谨慎。
一个 go.mod 文件最多可以包含一个 go 指令。如果不存在,大多数命令将添加一个带有当前 Go 版本的 go 指令。
toolchain
声明一个建议与此模块一起使用的 Go 工具链。仅当模块是主模块且默认工具链比建议的工具链旧时才生效。
有关更多信息,请参阅“Go 工具链”和 Go 模块参考中的toolchain 指令。
语法
toolchain toolchain-name
- 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-key
- 要应用的设置名称。可在 GODEBUG 历史记录中找到设置列表及其引入版本。
- debug-value
- 提供给设置的值。如果未另行指定,则
0禁用,1启用命名行为。
示例
- 使用新的 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.5 替换为同一模块的 v1.2.3 版本。
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。