Go Wiki:GOPATH

GOPATH 变量

使用超出标准库的依赖项进行 Go 开发是 使用 Go 模块 完成的。使用 Go 模块时,GOPATH 变量(在 Unix 上默认为 $HOME/go,在 Windows 上默认为 %USERPROFILE%\go)用于以下目的

有关 GOPATH 变量的完整详细信息,请参阅 go 命令文档。本页的其余部分涉及现已弃用的 GOPATH 开发模式。

GOPATH 开发模式

在 Go 模块之前,使用依赖项进行 Go 开发使用“GOPATH 开发模式”或简称“GOPATH 模式”。在 GOPATH 模式下,go 命令将 GOPATH 变量用于以下目的

弃用并移除 GOPATH 开发模式

Go 模块是 GOPATH 开发模式的替代品,旨在为整个 Go 生态系统添加包版本的概念。

从 GOPATH 开发模式到 Go 模块的过渡是渐进的,分布在许多 Go 版本中

请注意,移除 GOPATH 开发模式并不意味着移除 GOPATH 变量。它仍将用于本页顶部列出的目的。

常见问题解答

GOPATH 变量是否会被移除?

否。GOPATH 变量(在环境中设置或通过 go env -w 设置)不会被移除。它仍将用于确定默认二进制安装位置、模块缓存位置和校验和数据库缓存位置,如本页顶部所述。

我是否仍可以在 GOPATH/src/import/path 中编写代码?

可以。许多 Go 开发人员欣赏此约定提供的结构,并将其模块存储库签出到其中。开始使用模块所需的所有代码都是一个 go.mod 文件。请参阅 go mod init

如何在 GOPATH/src 中编译一个仓库以针对另一个仓库中所做的更改?

如果要在构建另一个模块时使用一个模块中的未发布更改,可以向另一个模块的 go.mod 添加 replace 行。

例如,如果你已将 golang.org/x/websitegolang.org/x/tools 检出到 $GOPATH/src/golang.org/x/website$GOPATH/src/golang.org/x/tools,那么要让 website 的本地构建自动使用 tools 中的更改,你需要将以下内容添加到 $GOPATH/src/golang.org/x/website/go.mod

replace golang.org/x/tools => ../tools

当然,replace 指令不了解 $GOPATH。如果你已将这两个检出到 $HOME/mycode/website$HOME/mycode/tools,则同一行也会正常工作。

为什么移除 GOPATH 开发模式?

从本质上讲,GOPATH 开发模式基本上自动提供所有这些类型的 replace 行,以便你为依赖项构建的代码是你碰巧在计算机上检出的代码。这意味着你的构建会受到你碰巧保留的旧检出内容的影响,而你可能已经忘记了这些内容。这意味着你在一台机器上获得的构建可能与另一台机器不同,即使从同一顶级仓库的同一版本开始。而且,这意味着你获得的构建可能与同一项目中另一位开发人员获得的构建不同。Go 模块解决了所有这些可重复性问题。所有这些问题的根本原因是 GOPATH 模式没有任何包版本的概念。

除了可重复性之外,Go 模块还提供了一种处理代理和安全下载的清晰方式。当你 git clone 一个项目然后获取其依赖项时,这些依赖项会经过加密检查(使用 go.sum 文件)以确保它们与原始开发人员使用的位相同。唯一可信的部分是顶级 git clone。这里同样如此,这只有在 Go 模块(与 GOPATH 模式相反)具有包版本的概念时才有可能。

对于 Go 自身的未来演进,模块明确标记了文件树的特定版本是用哪个版本的 Go 语言编写的。这使得在 Go 的更高版本中禁用有问题的特性(例如 string(1),许多人认为它生成 "1" 但实际上生成 "\x01"(Ctrl-A))成为可能,同时保持旧程序的构建(因为它们明确标记为已针对旧版本的 Go 编写)。

还有更多类似的示例。

在 GOPATH 开发模式中,所有这些都是不可能的,因为该模式目前存在。在不弃用 GOPATH 模式的情况下,我们无法推进生态系统的发展,也无法真正开始依赖 Go 模块的这些重要特性。

(你可能还会问:为什么不直接将这些内容添加到 GOPATH 模式中?答案是:我们已经这么做了,结果就是 Go 模块。)

何时决定弃用 GOPATH 开发模式?

最初的计划是在 Go 1.13 中弃用 GOPATH 模式,但我们希望花更多时间让尽可能多的 Go 用户的模块更健壮,因此弃用从该版本中推迟。关于问题 #41330和 golang-tools 组的讨论没有发现任何弃用 GOPATH 的剩余障碍,因此现在已将其安排在 Go 1.16 中,并将在未来的版本中删除,如上文时间表中所述。

如果我还有更多关于从 GOPATH 开发模式迁移到 Go 模块的问题,该怎么办?

请参阅golang.org/help以获取资源列表。如果这些都不合适,请随时在此提交问题。我们希望每个人都能成功采用 Go 模块。


此内容是Go Wiki的一部分。