仅供参考,大方向是对的。go命令 几个版本之间的功能改动还没捋清楚

大方向:官方先用GOPATH模式 约等于无, 三方提出了vendor机制完善,然后官方推出了Modules模式
主要不同在于 依赖包存放的位置,影响的是go的下载依赖包,编译依赖包相关的命令(go get,go install)


GO111MODULE=autoGO111MODULE=on

两个路径 (GOROOT、GOPATH)

  1. 安装go sdk,配置go环境变量
  2. Go env 查看环境变量
    • GOROOT: sdk安装目录
    • GOPATH: 项目路径
在 vendor 目录、GOPATH 目录、GOROOT 目录都可能存在依赖库(标准库、第三方库等)

1 . GOPATH 模式

  • $GOPATH :项目根路径
    • src :项⽬源代码
    • bin :可执行程序
    • pkg :第三⽅依赖库

运行方式

所有工程代码要求放在GOPATH/src目录下

缺点

  1. 没有版本控制的概念
  2. 所有项目都要放在 $GOPATH/src目录下,不在 $GOPATH/src 下就不能编译

2. vendor 特性/模式 (三方)

解决 GOPATH模式 所有项目都在$GOPATH/src目录的问题
可以随处可以创建项目,不用扎堆 src 目录下

  • 方案原理:本地化构建
    在每个项目下都创建一个 vendor 目录,每个项目所需的依赖都只会下载到自己vendor目录下.
    在使用包时,会先从当前项目下的 vendor 目录查找,然后GOPATH 中查找,都没找到最后在 GOROOT中查找。

  • 缺点
    放弃了依赖重用,使得冗余度上升

3. Go Modules 模式(模块感知模式)

1. 可以管理依赖的版本
2. 工程不用全放在gopath/src
  • 主要改动:
    1. GOMODULE模式下所有依赖的包存放在$GOPATH/pkg/mod目录下
    2. 项目中需要有go.mod文件,来应用$GOPATH/pkg/mod

mod 相关环境变量

# Modules 开关
GO111MODULE="auto"
# Go 模块代理(脱离VCS版本控制方式,直接通过镜像站点来拉取)
GOPROXY="https://proxy.golang.org,direct" # 国内无法访问
# 保证拉取到的模块版本数据未经过篡改
GOSUMDB="sum.golang.org" # 国内无法访问
# 私有模块配置(用于Go 模块代理无法访问到的地方,如私有库)
GONOPROXY=""
GONOSUMDB=""
GOPRIVATE=""

go.mod 文件

启用了 Go modules 的项目,初始化项目时,会生成一个 go.mod 文件。描述了当前项目(也就是当前模块)的元信息

# module:用于定义当前项目的模块路径。
module github.com/eddycjy/module-repo

# go:用于标识当前模块的 Go 语言版本,值为初始化模块时的版本,目前来看还只是个标识作用。
go 1.13

# require:用于设置一个特定的模块版本。
require (
    example.com/apple v0.1.2
    example.com/banana v1.2.3
    example.com/banana/v2 v2.3.4
    example.com/pear // indirect	# indirect 标识表示该模块为间接依赖
    example.com/strawberry // incompatible
)

# exclude:排除一个特定的模块版本。
exclude example.com/banana v1.2.4

# replace:用于将一个模块版本替换为另外一个模块版本。
replace example.com/banana => example.com/fish

go mod 命令

命令作用
go mod init生成 go.mod 文件
go mod download下载 go.mod 文件中指明的所有依赖
go mod tidy整理现有的依赖 (拉取缺少的模块,移除不用的模块)
go mod graph查看现有的依赖结构
go mod edit编辑 go.mod 文件
go mod vendor将依赖复制到vendor目录下
go mod verify校验一个模块是否被篡改过
go mod why查看为什么需要依赖某模块
$GOPATH/pkg/mod$GOPATH/pkg/sumdb

两个命令

go get xxx(下载xxx第三方依赖包并安装)

# 升级特定模块。
$ go get golang.org/x/net

# Upgrade modules that provide packages imported by packages in the main module.
$ go get -u ./...

# 升级或降级到模块的特定版本。
$ go get golang.org/x/text@v0.3.2

# 升级到模块的指定分支
$ go get golang.org/x/text@master

# 删除对模块的依赖,并将需要它的模块降级到不需要它的版本。
$ go get golang.org/x/text@none

go get会做两件事:

go install

拉取的过程总共分为了三大步,分别是 finding(发现)、downloading(下载)以及 extracting(提取), 并且在拉取信息上一共分为了三段内容:

go install xxx(安装xxx二进制可执行文件 )

# 安装程序的最新版本
$ go install golang.org/x/tools/gopls@latest

# 安装程序的特定版本
$ go install golang.org/x/tools/gopls@v0.6.4

# 在当前目录中安装模块所选版本的程序
$ go install golang.org/x/tools/gopls

# 在目录中安装所有程序
$ go install ./cmd/...

go install 是建立在 GOPATH 环境变量上的,无法在独立的目录里使用 go install。

go install 会生成可执行文件直接放到bin目录下

版本变化

go install = 用来编译安装本地项目。
go get = 下载 Go 包 + go install

  • go 1.16
    go get 将二进制安装相关的功能都转移到了 go install, 仅作为用于编辑 go.mod 文件的命令存在。
  • go 1.17
    开始官方不建议(deprecated)用于安装二进制可执行文件, 不能使用 go get 命令安装 Go 程序了
  • go 1.18
    开始不再支持安装。选项-d未来将成为默认参数,仅执行下载,不进行安装
    go get 的行为就等同于我们现在执行 go get -d 命令了,仅需下载源码,并将依赖添加至 go.mod

不同模式的命令区别

1. gopath模式

在工程经过go build、go install或 go get等指令后,会将拉取的第三方xxx依赖包放在GOPATH/src目录下

2. go vendor模式

go build 时的应用路径搜索调整成为 优先搜当前工程路径/vendor目录

2. go module模式
Go Modules 模式下,下载的包是存在 $GOPATH/pkg/mod 目录下的
go get {模块名}@{最新版本: latest|分支: master|tag: v0.3.2|hash: 342b2e}
go mod tidygo mod vendor