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
。