乐趣区

关于golang:Go-116-中关于-go-get-和-go-install-你需要注意的地方

Go (golang) 已于 18 日公布了 1.16 beta1 版本,至此其主体性能曾经根本确定。我看大多数人都在关注 Go 在苹果 (Apple) M1 上的反对,甚至 Go 官网博客中也有一篇专门的阐明 Go on ARM and Beyond,来介绍 Go 在此方面的反对。

我就不凑热闹了,我来聊聊 Go 1.16 中对于 go getgo install 你须要留神的中央。

目前 Docker 官网镜像尚未公布,我是本地构建了个镜像来应用。

(MoeLove) ➜  go version
go version go1.16beta1 linux/amd64

概览

Go 1.16 中蕴含着大量的 Modules 相干的更新,具体内容可间接查看其 Release Note。整体而言,蕴含以下要点:

  • GO111MODULE 默认为 on,如果要复原到之前的行为,则须要将 GO111MODULE 设置为 auto,这样差不多意味着 GOPATH 模式要逐渐淡出人们的视线了;
  • go install 命令能够承受一个版本后缀了,(例如,go install sigs.k8s.io/kind@v0.9.0),并且它是在模块感知的模式下运行,可疏忽当前目录或下层目录的 go.mod 文件。这对于在不影响主模块依赖的状况下,装置二进制很不便;
  • 在未来,go install 被设计为“用于构建和装置二进制文件”,go get 则被设计为“用于编辑 go.mod 变更依赖”,并且应用时,应该与 -d 参数共用,在未来版本中 -d 可能会默认启用;
  • go buildgo test 默认状况下不再批改 go.modgo.sum。可通过 go mod tidygo get 或者手动实现;

总结而言,对于 go installgo get 必须要留神的是:

  • 基本上 go install <package>@<version> 是用于命令的全局装置:

    • 例如:go install sigs.k8s.io/kind@v0.9.0;
  • go get 装置二进制的性能,后续版本将会删除;
  • go get 次要被设计为批改 go.mod 追加依赖之类的,但还存在相似 go mod tidy 之类的命令,所以应用频率可能不会很高;

Go 1.16 中已解决的工具装置问题

到目前为止,Go 始终应用 go get 命令,将咱们须要的工具装置到 $GOPATH/bin 目录下,但这种形式存在一个很重大的问题。go get 因为具备更改 go.mod 文件的能力,因而咱们 必须要防止执行 go get 命令时,让它接触到咱们的 go.mod 文件 ,否则它会将咱们装置的工具作为一个依赖。

目前的解决方案通常是:

(MoeLove) ➜  cd $(mktemp -d); GO111MODULE=on go get sigs.k8s.io/kind@v0.9.0

自 1.16 开始,咱们能够间接应用上面的形式:

(MoeLove) ➜  go install sigs.k8s.io/kind@v0.9.0

十分的简略直观。须要留神的是 go install <package>@<version> 是从 1.16 开始减少的,无论你以后是否在一个模块下,此命令都会在 $GOPATH/bin 下装置指定版本的工具。

此外因为 Go 1.16 中 GO111MODULE 默认是关上的,go install 不会批改 go.mod 之类的文件,不会造成任何意外。

留神:

@version 只能装置主软件包。非主程序包不受此格局束缚。

对于不带 @versiongo install

  • 在模块外,不带 @version 是无奈装置的,会有如下谬误:
(MoeLove) ➜  go install  -v sigs.k8s.io/kind
go install: version is required when current directory is not in a module
        Try 'go install sigs.k8s.io/kind@latest' to install the latest version
  • 如果你在模块目录中,并且你不带 @version 执行装置的话,只能装置 go.mod 中曾经蕴含的版本。并且不能装置未呈现在 go.mod 中的包。
(MoeLove) ➜  mkdir -p /go/src/github.com/moelove/iris
(MoeLove) ➜  cd /go/src/github.com/moelove/iris
# 初始化模块
(MoeLove) ➜  /go/src/github.com/moelove/iris go mod init
go: creating new go.mod: module github.com/moelove/iris
(MoeLove) ➜  /go/src/github.com/moelove/iris cat go.mod 
module github.com/moelove/iris

go 1.16


# 不带 @version 无奈装置
(MoeLove) ➜  /go/src/github.com/moelove/iris go install -v sigs.k8s.io/kind
no required module provides package sigs.k8s.io/kind; try 'go get -d sigs.k8s.io/kind' to add it

# 用 go get -d 下载
(MoeLove) ➜  /go/src/github.com/moelove/iris go get -d sigs.k8s.io/kind
go get: added sigs.k8s.io/kind v0.9.0

# 能够看到曾经被增加到了模块依赖中
(MoeLove) ➜  /go/src/github.com/moelove/iris cat go.mod 
module github.com/moelove/iris

go 1.16

require sigs.k8s.io/kind v0.9.0 // indirect

# 删除本地的 kind 工具
(MoeLove) ➜  /go/src/github.com/moelove/iris which kind
/go/bin/kind
(MoeLove) ➜  /go/src/github.com/moelove/iris rm /go/bin/kind
(MoeLove) ➜  /go/src/github.com/moelove/iris which kind

# 不带 @version 进行装置
(MoeLove) ➜  /go/src/github.com/moelove/iris go install -v sigs.k8s.io/kind
(MoeLove) ➜  /go/src/github.com/moelove/iris which kind
/go/bin/kind
(MoeLove) ➜  /go/src/github.com/moelove/iris kind version
kind v0.9.0 go1.16beta1 linux/amd64

对于 go getgo.mod

go get 将二进制装置相干的性能都转移到了 go install, 仅作为用于编辑 go.mod 文件的命令存在。在后续版本(打算是 Go 1.17)中删掉 go get 装置二进制的性能,接下来 go get 的行为就等同于咱们当初执行 go get -d 命令了,仅需下载源码,并将依赖增加至 go.mod 即可。

go.mod 如何编辑

在 Go 1.16 中,另一个行为变更是 go buildgo test 不会主动编辑 go.mod 了,基于以上信息,Go 1.16 中将进行如下解决:

  • 通过在代码中批改 import 语句,来批改 go.mod

    • go get 可用于增加新模块;
    • go mod tidy 删除掉无用的模块;
  • 将未导入的模块写入 go.mod:

    • go get <package>[@<version>];
    • go mod tidy 也能够;
    • 手动编辑;

从 1.15 降级须要留神什么?

因为 go buildgo test 不会主动编辑 go.mod 了,所以能够将本来的行为通过 go mod tidy 独特解决。

总结

Go 1.16 中 go installgo get 方面有些不兼容的变更,然而 1.16 中模块更加简洁,缩小了应用时的心智累赘,我还是很期待这个版本的。


欢送订阅我的文章公众号【MoeLove】

退出移动版