去获取和去安装有什么区别?

在使用 go工具一段时间后,它看起来像 go get:

  1. (可选)下载,
  2. 编译,
  3. 安装

一个软件,而 go install只是

  1. 编译
  2. 安装

在这种情况下,为什么存在 go install命令,因为 go get取代了它?

88371 次浏览

在本地工作时,go install是工作流的一部分。假设您想使用库,但由于某种原因需要进行更改。你可以这么做:

  • go get -d library,它只下载它;
  • 更改已下载的软件包;
  • 安装本地版本。

据我所知,go get没有标志表明它应该 没有下载,所以它不能在这里取代 go install

当您从头开发一个新包时,使用相同的工作流程。

编辑: 六年后,Go 1.16更新并澄清了 go installgo get: https://tip.golang.org/doc/go1.16#modules的用法

有或没有版本后缀(如上所述)的 go install现在是模块模式下 构建和安装软件包的推荐方法。go get应该与 -d标志一起使用到 在不构建包的情况下调整当前模块的依赖关系,不建议使用 go get来构建和安装软件包。在将来的版本中,-d标志将始终启用。

go get按照以下顺序做了两件主要的事情:

  • 下载并在 $GOPATH/src/<import-path>中保存导入路径中命名的包(源代码)及其依赖项,然后

  • 执行 go install

-d标志(go get -d)指示 go get在下载包之后停止; 也就是说,它指示 go get不要执行 go install


区别在于:

go get//验证是否需要下载软件包,如果需要下载,然后编译

go install//跳过软件包下载部分,只需编译(如果有软件包丢失,这将抛出一个错误)


关于 GOPATH环境变量

围棋工具使用的是 GOPATH环境变量。它必须设置为能够 getbuildinstall包,并指定工作区的位置。这可能是开发围棋代码时唯一需要设置的环境变量。

同样,GOPATH不应该指向 Go 安装,而是应该指向您的工作区。

例如,在 Windows 上,如果确定工作区位于 c:\gowork\,则需要将 GOPATH值设置为 c:\gowork

enter image description here

源代码应该位于 c:\gowork\src\<some project folder>\,在命令提示符下从 c:\gowork\src\<some project folder>\运行 go get之后,您将看到正在创建的 c:\gowork\bin\c:\gowork\pkg\

请注意,Go 1.16(Q12021)将使这种差异更加明显,CL 266360作为 第40276期的一部分实现:

go install现在接受带有版本后缀的参数(例如,go install example.com/cmd@v1.0.0)。
这会导致工作目录或任何父目录(如果有的话)中的 go install变为 以模块感知模式构建和安装包忽略 go.mod文件
这是 对于安装可执行程序而不影响主模块的依赖关系非常有用

有或没有版本后缀(如上所述)的 go install现在是以模块模式构建和安装包的推荐方法。

go get 应该与 -d标志一起使用,以便在不构建包的情况下调整当前模块的依赖关系,以及 不建议使用 go get来构建和安装包
在未来版本中,-d标志将始终启用里。


在2022年6月(在1.19前转到1.18) ,Chris Siebenmann详细介绍“ go install可以安装的限制”。

它涉及一个具有 replace指令的模块:

如果你克隆了 储存库并在其中运行‘ go install’,那么一切都会正常工作,并且你的 $HOME/go/bin中会有一个 gospy二进制文件。

但是,正如我们在这里所看到的,‘ go install ...@latest’的工作方式不同,以至于 return 指令导致了这个错误。

这将触发错误消息:

go: github.com/monsterxx03/gospy@latest (in github.com/monsterxx03/gospy@v0.5.0):
The go.mod file for the module providing named packages contains one or
more replace directives. It must not contain directives that would cause
it to be interpreted differently than if it were the main module.

“安装”的帮助明确指出了这种模式:

没有模块被认为是“ main”模块。

如果命令行中包含包的模块有一个 go.mod文件,那么它必须包含指令(replaceexclude) ,这些指令会导致与主模块不同的解释。
模块不能要求自身的更高版本。

参见:

  • 问题44840 : cmd/go: go install cmd@version错误时,与 main包模块有 replace指令
  • 问题40276 : cmd/go: go install应该在模块模式 在外面 a 模块中安装可执行程序
  • 问题45099 : x/tools/gopls: 无法安装 gopls v0.6.8(说明问题)

建议:

切换到使用 < a href = “ https://Go.dev/ref/mod # workspace”rel = “ nofollow norefrer”> Go workspace 进行本地开发,并完全删除 go.mod replace指令。

正如 贝丝 · 布朗在“ 熟悉工作区”中提到的:

以前,要向一个模块添加一个特性并在另一个模块中使用它,您需要发布对第一个模块的更改,或者使用针对本地未发布模块更改的 replace指令发布依赖模块的 编辑 go.mod文件

为了在没有错误的情况下发布,在发布对第一个模块的本地更改之后,必须从依赖模块的 go.mod文件中发布 replace指令。

使用 Go 工作区,您可以使用工作区目录根目录中的 去工作吧文件控制所有依赖项。
go.work文件有 usereplace指令,覆盖单独的 go.mod文件,所以不需要单独编辑每个 go.mod文件。