GOPATH

之前的依赖管理工具,现在已经淘汰

  • GOROOT: GO 语言安装目录的环境变量,属于 GO 语言顶级目录
  • GOPATH: 第三方库和项目私有库都在 GOPATH 环境变量指定的目录中,再进行依赖查找的时候,编译器会依次从 GOROOT/src , GOPATH/src 中查找

GOPATH 的缺点,无法在同一个 GOPATH 目录中保存两个库的不同版本,并且不同项目无法共享 GOPATH

Vendor

Go1.6 开始启用,但是随着 Go1.11 中的 go module 发布,也就淘汰了

使用一个 vendor 目录,把各种依赖存放在这一个目录下即可,搜索顺序: 各级 vendor > GOPATH

Module

go Modulepackage 的关系如下:

  • 一个仓库中包含一个或者多个 Go module
  • 每一个 Go moudle 中包含一个或者多个 Go package
  • 每一个package 包含一个或者多个Go源文件

语义版本规划,注意到一个依赖的版本号名称含义如下:

版本格式v(major).(minor).(patch)中major指的是大版本,minor指小版本,patch指补丁版本。

  • major: 当发生不兼容的改动时才可以增加major版本;比如v2.x.yv1.x.y是不兼容的;
  • minor: 当有新增特性时才可以增加该版本,比如v1.17.0是在v1.16.0基础上加了新的特性,同时兼容v1.16.0
  • patch: 当有bug修复时才可以 增加该版本,比如v1.17.1修复了v1.17.0上的bug,没有新特性增加;

基本使用

初始化module

如果一个项目想要使用 go module ,那么必须自己成为一个 go module , 并且在这一个机制下,项目的名称记录在 go.mod 中,并且可以手动创建,也可以使用如下命令生成:

go mod init [module]

再编译运行项目之前,需要使用 go get 指令来下载依赖,同时第一次使用 go get 会生成一个 go.sum 文件,记录着依赖包的哈希值

replace 指令

go.mod文件中通过指令来声明 module信息,用于控制命令行工具进行版本选择,以供四个指令可以使用:

  • module: 声明 moudle 名称
  • require: 声明替换依赖以及版本号
  • replace: 替换 require 中生命的依赖以及版本号
  • exclude: 禁用指定的依赖

注意到可以使用 go list -m 来查看最终使用的包的版本信息等

注意到 replace 替换之后,代码中不需要重新改变 import 的内容,只需要继续使用即可,但是相关的依赖已经被替换了,语法结构如下:

replace (
	XXX => XXX
)

应用场景:

  • 替换无法下载的包
  • 调试依赖包
  • 使用 fork 仓库
  • 禁止被依赖(也就是许多 module 不希望被直接引用,所以就使用了 replace)

exclude指令

exclude指令用于排除依赖,使用方式如下:

exclude XXX(需要排除的依赖名称)

比如当使用了如下 exclude 命令:

exclude github.com/google/uuid v1.1.0

如果你的 go.mod 中包含了这一个依赖,那么此时利用 go get 之后,go mod 文件如下:

module github.com/renhongcai/gomodule

go 1.13

require (
    github.com/google/uuid v1.1.1
    github.com/renhongcai/exclude v1.0.0
    golang.org/x/text v0.3.2
)

replace golang.org/x/text v0.3.2 => github.com/golang/text v0.3.2

exclude github.com/google/uuid v1.1.0

indirect 指令

总是出现在 require 指令的项的后面,比如 // indirect 作用就是表示这一个依赖是一个间接依赖

间接依赖的存在作用就是指定一个包的依赖情况,也就是需要记录依赖的版本号,同时还需要记录这一个依赖的其他依赖情况

Go module 中可以使用 go mod why 命令来解释为什么依赖某一个软件包,可以使用 go mod why -m <pkg> 命令查看依赖的软件包

go mod 常用子命令

  • go mod 命令的子命令和作用如下:
go mod download 下载依赖的module到本地cache(默认为$GOPATH/pkg/mod目录) 
go mod edit 编辑go.mod文件 
go mod graph 打印模块依赖图 
go mod init 初始化当前文件夹, 创建go.mod文件 
go mod tidy 增加缺少的module,删除无用的module 
go mod vendor 将依赖复制到vendor下 
go mod verify 校验依赖 go mod why 解释为什么需要依赖
  • go get 的作用,执行 go get 可以下载依赖包,并且可以指定下载的版本:
    • go get -u 将升级到最新版本的次要版本或者修订版本
    • go get -u=patch 将会升级到最新的修订版本
    • go get package@version 将会升级指定的版本号version
    • 如果下载所有的依赖也可以使用 go mod download