Golang中$GOPATH与$GO111MODULE的选择与使用
Golang中$GOPATH与$GO111MODULE的选择与使用 作为初学者,我想了解使用$GOPATH或$GO111MODULE的最佳实践。go get命令是否需要设置$GOPATH,以便将所有依赖项下载到$GOPATH目录中?
谢谢
您提到有可能废弃 GOPATH,但看起来至少 go get 命令可能还需要它。那么我想知道,一旦我们不再使用 GOPATH,是否会有其他方式来实现 go get 的功能?
感谢您的分享,您的见解非常具有启发性!
更多关于Golang中$GOPATH与$GO111MODULE的选择与使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
即使现在,我不仅对这些句子感到更加痛苦,更对GOPATH和GO111MODULE之间的混淆感到困惑😂
go get命令不仅会下载程序,还会进行编译并将编译后的二进制文件放入$GOPATH/bin中吗?
由于我现在使用Goland IDE,并且假设这些go工具(我可以将golangci-lint视为go工具之一吗)都由IDE自动处理,使用go get的情况就更少了。同意吗?
感谢 @hollowaykeanho。还有一些后续问题。
-
如果我们使用
go get下载一个开箱即用的程序到GOPATH目录,当我们需要这个程序时,GO 是否会自动在GOROOT和GOPATH中搜索它? -
我认为我们也可以使用
go get为我们的项目下载包或依赖项,由于我们使用的是GO111MODULE,通常不使用GOPATH目录,GO 如何知道在哪里找到这些为项目下载的依赖项?GO 是否也会自动在GOPATH中搜索我们项目使用的任何依赖项(我认为不会)? -
go get -u,根据我的理解,这里的-u表示更新,会将您的本地更新发送到 github(在这个例子中)。如果我们没有任何更新 github 的计划,是否需要使用-u?我看到大多数人使用-u,所以想在这里澄清一下。
jameswang2015:
go get不仅会下载程序,还会进行编译并将编译后的二进制文件放入$GOPATH/bin吗?
是的,自动完成。你会在 GOPATH/src 中获得源代码,在 GOPATH/bin 中获得二进制文件。
jameswang2015:
既然我现在使用 Goland IDE,并且假设这些
go tools(我可以将golangci-lint视为go tools之一吗)都由 IDE 自动处理,那么使用go get的情况就更少了。同意吗?
关于使用 go get 获取 Go 编程工具,这超出了我的了解范围。这取决于 IDE 的健壮性。我无法深入回答 IDE 部分,因为我是一个过时的 Linux vi 用户,仍然在编写最多 80 列的代码。
不,你仍然需要熟悉 go get。它只是一个简单、基本且分发 Go 程序的另一种方式(那些包含 main 代码的程序,比如非常有用的 Hugo)。在以下情况下你仍然需要它:
- 开发任何 CI 或基础设施工具。使用官方安装程序或通过 Docker 镜像变通处理的情况除外。
- 在严格且过时的系统上生存(比如我使用的稳定版 Debian),由于许多原生软件包都已过时,这种方式很重要。
- 快速下载最新版本的 Go 程序,无需处理那些繁琐的打包事宜,比如支付每年 125 美元 / 25 美元的会员费以及签署像我汽车保险杠一样厚的协议。
- 作为分发你的 Go 程序的最后手段。
jameswang2015:
即使现在,我不仅觉得这些句子更让人头疼,而且对
GOPATH和GO111MODULE之间的混淆更感到困惑。
太长不看版:
- 请设置
GOPATH并顺其自然 - 使用模块进行开发;使用
go get下载程序 - 有疑问?尽管再问
- 不要给自己太大压力;放松一下,喝杯绿茶。
Go 是一个非常强大的工具。让时间来滋养你。欢迎加入,Gopher!🚀🎆
jameswang2015:
如果我们使用"go get"下载一个开箱即用的程序到GOPATH目录,当我们需要这个程序时,GO会自动在GOROOT和GOPATH中搜索它吗?
当你需要使用像示例中这样的Go程序时(这是一个强大的linter来检查你的Go源代码),它会自动在GOPATH中搜索。任何编译后的二进制文件都存储在GOBIN下,这本质上是GOPATH/bin。
jameswang2015:
我认为我们也可以使用
go get为我们的项目下载包或依赖项,由于我们使用GO111MODULE通常不使用GOPATH目录,GO如何知道在哪里找到这些为项目下载的依赖项?GO是否也会自动在GOPATH中搜索我们项目使用的任何依赖项(我认为不是这样)?
模块使用不同的机制来组织依赖项。据我理解,它不再使用GOPATH(这是目标)。模块高度依赖go.mod文件的require子句来提供依赖项列表。更多信息,我建议你花些时间阅读这些文档,并用一些虚拟仓库进行深入实验:
附注:我仍在等待开发人员的指示,以便最终放弃GOPATH。到目前为止,我仍然在GOPATH中安装二进制文件。
jameswang2015:
go get -u,根据我的理解,这里的-u表示更新,会将你的本地更新发送到github(在这个例子中)。如果我们没有任何更新github的计划,是否需要使用-u?我看到人们大多使用-u,所以想在这里澄清一下
简单来说,-u参数是从Github拉取最新内容到你的本地仓库,并重新编译相应的二进制文件(如果有的话)。这不是相反的方向。因此,名称update代表"更新你的本地仓库"。
要从本地仓库推送到Github,你使用传统的方式进行开发,即进入目录并执行git push。(你能感受到我们在go模块之前的痛苦吗,过去仅仅通过阅读那句话?)
如果你使用较新的Go版本,比如最新版本,请忽略这一点。请使用模块。
在Go语言中,$GOPATH和$GO111MODULE是管理依赖和项目结构的重要机制。随着Go模块(Go Modules)的引入,$GO111MODULE成为现代Go开发中的推荐方式。以下是详细解释和示例代码。
1. $GOPATH 的作用和使用
$GOPATH是Go早期版本中用于管理项目依赖和工作区的环境变量。它定义了三个子目录:src(源代码)、pkg(编译后的包文件)和bin(可执行文件)。在模块系统出现之前,所有Go项目都必须位于$GOPATH/src目录下,并且go get命令会将依赖下载到$GOPATH/src中。
示例:
假设$GOPATH设置为/home/user/go,运行go get github.com/example/pkg会将包下载到/home/user/go/src/github.com/example/pkg。
export GOPATH=/home/user/go
go get github.com/example/pkg
2. $GO111MODULE 的作用和使用
$GO111MODULE是控制Go模块行为的环境变量,可设置为on、off或auto(默认值)。从Go 1.11开始引入模块支持,允许在项目目录外管理依赖,无需依赖$GOPATH。推荐在Go 1.16及以上版本中默认启用模块(即GO111MODULE=on)。
- GO111MODULE=on:强制使用模块模式,忽略
$GOPATH。 - GO111MODULE=off:禁用模块模式,回退到
$GOPATH行为。 - GO111MODULE=auto:如果当前目录或父目录包含
go.mod文件,则启用模块模式;否则使用$GOPATH。
在模块模式下,依赖项存储在模块缓存中(默认在$GOPATH/pkg/mod),而不是$GOPATH/src。
3. 最佳实践和 go get 命令
对于新项目,强烈推荐使用Go模块(设置GO111MODULE=on),因为它简化了依赖管理,支持版本控制,并允许项目位于任意目录。go get命令在模块模式下不需要$GOPATH设置;它会将依赖项下载到模块缓存中,并在go.mod文件中记录依赖。
示例代码:
创建一个新项目目录,初始化模块,并使用go get下载依赖。
# 创建项目目录(无需在GOPATH内)
mkdir myproject
cd myproject
# 初始化Go模块,指定模块名
go mod init myproject
# 启用模块模式(如果未默认设置)
export GO111MODULE=on
# 使用go get下载依赖,例如gin框架
go get github.com/gin-gonic/gin
这会在当前目录生成go.mod和go.sum文件,记录依赖信息。依赖项被存储在全局模块缓存中(如$GOPATH/pkg/mod)。
4. 总结
- 对于初学者,从Go 1.16开始,默认启用模块模式,无需手动设置
$GOPATH。项目可以放在任何位置。 go get命令在模块模式下不依赖$GOPATH;它使用模块缓存管理依赖。- 如果维护旧项目,可能需要设置
GO111MODULE=off来兼容$GOPATH。
通过采用Go模块,可以避免$GOPATH的复杂性,实现更灵活的依赖管理。


