希望在 Go 1.14 中会有一个新标志go get
,它完全符合您的要求。这在问题#30515 “cmd/go:提供一致的全局安装命令”中进行了跟踪。
在此之前,您有几个不同的选择。
转到 1.12 和 1.13:更改目录
如果您使用的是 Go 1.12 或更高版本,最简单的解决方案可能是在当前模块之外移动到一个目录,而无需go.mod
事先执行go get
,例如:
$ cd /tmp
$ go get github.com/foo/bar@v1.2.3
$ cd - # return to prior directory
去 1.11、1.12、1.13+:戈宾
gobin是一个模块感知命令,用于安装或运行二进制文件,提供额外的灵活性,包括无需更改当前模块的go.mod
. 有关更多详细信息,请参阅gobin
自述文件和常见问题解答。
Go 1.11:临时模块
如果你使用带模块的 Go 1.11,第一步可能是升级到 Go 1.12 或 1.13,因为模块有很多改进。如果您需要使用 Go 1.11 并且想要使用@version
语法而不更新当前模块的go.mod
,那么一种方法是创建一个临时模块:
cd $(mktemp -d) && go mod init tempmod && go get github.com/foo/bar@v1.2.3
@version
这是因为在 Go 1.11 中,除非你在一个模块中,否则你不能使用语法,这在 Go 1.12 中被放宽了。这个方法已经被@rogpeppe 的一个简单的shell 脚本自动化了。
额外细节
一般来说,go
module-module 中的命令总是确定它“在”哪个模块,这取决于您调用go
命令时的当前工作目录。(您可以类比make
没有任何 args 将如何在当前工作目录中查找 makefile,或者历史上go build
没有任何 args 将如何构建当前工作目录等)。
使用模块,在当前工作目录或其任何父目录中go get
查找文件,并将使用其中列出的约束作为解决版本的一部分,并根据需要更新. 这就是为什么如果您从现有模块中运行文件会更新的原因。go.mod
go get
go.mod
go.mod
go get
go.mod
go get
另一方面,从 Go 1.12 开始,如果您所在的目录不属于任何模块(即该目录没有go.mod
,也没有它的任何父目录),则无需go.mod
更新,但是该go
命令仍然能够在模块模式下运行并使用@version
语法。
从Go 1.12 发行说明:
当 GO111MODULE 设置为 on 时,go 命令现在支持模块目录之外的模块感知操作,前提是这些操作不需要解析相对于当前目录的导入路径或显式编辑 go.mod 文件。go get、go list 和 go mod download 等命令的行为就像在具有初始空要求的模块中一样。在这种模式下, go env GOMOD 报告系统的空设备(/dev/null 或 NUL)。