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 getgo mod tidygo mod edit 命令。

有关 go 命令的参考,请参阅Command go。您可以通过键入 go help command-name 从命令行获取帮助,例如 go help mod tidy

另请参阅

  • Go 工具在您使用它们管理依赖项时会更改您的 go.mod 文件。有关更多信息,请参阅管理依赖项
  • 有关 go.mod 文件的更多详细信息和约束,请参阅Go 模块参考

示例

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.modgo.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.0go1.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 getgo 命令时,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 mytoolgo 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 对模块的搜索重定向到替换位置的效果。您无需更改包导入路径即可使用替换路径。

在构建当前模块时,使用 excludereplace 指令控制构建时依赖项解析。这些指令在依赖于当前模块的模块中将被忽略。

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 指令排除间接需要但由于某种原因无法加载的模块的特定版本。例如,您可以使用它来排除具有无效校验和的模块版本。

在构建当前模块(您正在构建的主模块)时,使用 excludereplace 指令控制构建时依赖项解析。这些指令在依赖于当前模块的模块中将被忽略。

您可以使用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-lowversion-high 都包含在该范围内。
rationale
可选注释,解释撤回的原因。可能会显示给用户。

示例

  • 撤回单个版本

    retract v1.1.0 // Published accidentally.
    
  • 撤回版本范围

    retract [v1.0.0,v1.0.5] // Build broken on some platforms.
    

注意事项

使用 retract 指令指示您的模块的先前版本不应再使用。用户将不会使用 go getgo mod tidy 或其他命令自动升级到已撤回的版本。用户将不会看到已撤回的版本作为 go list -m -u 的可用更新。

已撤回的版本应保持可用,以便已依赖它们的用户能够构建其包。即使已撤回的版本从源仓库中删除,它仍可能在镜像(例如 proxy.golang.org)上可用。依赖于已撤回版本的用户在对相关模块运行 go getgo list -m -u 时可能会收到通知。

go 命令通过读取模块最新版本中 go.mod 文件中的 retract 指令来发现已撤回的版本。最新版本按优先级顺序为

  1. 其最高的发布版本(如果有)
  2. 其最高的预发布版本(如果有)
  3. 仓库默认分支尖端的伪版本。

当您添加撤回时,您几乎总是需要标记一个新的、更高的版本,以便命令在模块的最新版本中看到它。

您可以发布一个唯一目的是发出撤回信号的版本。在这种情况下,新版本也可能撤回自身。

例如,如果您意外地标记了 v1.0.0,则可以使用以下指令标记 v1.0.1

retract v1.0.0 // Published accidentally.
retract v1.0.1 // Contains retraction only.

不幸的是,一旦版本发布,就无法更改。如果您稍后在不同的提交中标记 v1.0.0go 命令可能会在 go.sum校验和数据库中检测到不匹配的校验和。

模块的已撤回版本通常不会出现在 go list -m -versions 的输出中,但您可以使用 -retracted 来显示它们。有关更多信息,请参阅 Go 模块参考中的go list -m