这是我参与「第五届青训营」伴学笔记创作活动的第 3 天
前言
本次Go语言进阶主要分为并发编程、依赖管理、单元测试、项目实这四个板块。这次笔记主要围绕依赖管理进行记录。
依赖管理
学会站在巨人的肩上
Go 语言依赖管理的主要用处是跟踪和安装您的项目所需的 Go 包(也称为依赖项)。学会站在巨人的肩上,也就是利用封装好的、经过验证的开发组建或工具来提法自己的开发效率。
背景
工程项目不可能从0~1进行编码
对于hello world以及类似的单体函数只需要依赖原生SDK,而实际工程会相对复杂,我们不可能基于标准库0~1编码搭建,而更多的关注业务逻辑的实现,而其他的涉及框架、日志、driver、以及collection等一系列依赖都会通过sdk的方式引入,这样对依赖包的管理就显得尤为重要。
官理依赖库
它可以帮助您维护包依赖性,并保证你的项目始终使用有效版本的包。通过使用依赖管理,您可以避免在分发项目时手动安装其他包或者在多人协作时遇到版本冲突问题。
Go 依赖管理演进
GO 依赖管理主要经历了三个阶段
GOPATH -> GO VENDOER -> GO MODULE
依赖管理可以根据不同的环境(项目)依赖的版本不同来控制依赖库的版本。
GOPATH
GOPATH 是Go语言支持的一个环境变量,value是Go项目的工作区。 目录结构:
src:存放Go项目源代码 bin:存放Go项目编译的二进制文件,可执行程序 pkg:存放Go项目编译的中间产物,加速编译速度
运行方式
GOPATH依赖管理的运行方式是在终端下,使用go get命令来下载指定的package,并将其放置在$GOPATH/src目录中。 GOPATH/src/项目名并取消包内部依赖话处理。当程序执行时,go会从GOPATH/src/开始寻找对应的包。此外,go会去检测GOMODULES文件夹中的每一个module list文件(.mod和.sum)以及downloads文件夹中保存的新版本情况,然后更新其本地存储的module list,如果有必要就去进行更新或者重新安装。
弊端
在A和B依赖于某一个package的不同版本,无法实现package的版本控制。
GO Vendor
项目目录下增加 vendor 文件,所有依赖包副本形式放在 $ProjectRoot/vendor 依赖寻址方式:vendor =>GOPATH
Go Vendor 会首先检测你的项目目录下是否存在一个“vendor”文件夹,如果存在这样一个文件夹并且它里面有你要引用的某个包,那么该引用就会使用此文件夹里面对应版本的这个package。否则就会到GOPATH上去找这个package。
它通过每个项目引入一份依赖的副本,解决了多个项目需要同一个 packace依赖的冲突问题。
弊端
无法控制依赖的版本
更新项目又可能出现依赖冲突,导致编译出错
Go Module
为 Go 语言提供了一个官方的包管理工具,可以用来管理依赖,检测冲突和对外发布 package。
Go modules 允许你在一个单独的文件中保存程序所需要的所有依赖;
它还支持版本管理和标记,使你能够在你的项目中使用特定版本的依赖包。
Go modules 还能够减少重复的代码,它将会在多个主机上存储依赖并进行副本检测以减少重复。
通过 go mod 命令可以更好的管理依赖和版本。它可以显式的指定包的版本、使用特定的代码树(例如 git 标签或者 commit hash)
此外,go mod 还可以很方便地处理代码重用的问题,开发者可以直接将其他 modules 加入到当前 module 中,而不用重新下载或者手动修改代码。
依赖管理三要素
- 配置文件 描述依赖
go.mod - 中心仓库管理依赖库
Proxy - 本地工具
go get/mod
依赖配置 go.mod
首先模块路径用来标识一个模块,从模块路径可以看出从哪里找到该模块,如果是github前级则表示可以从Github 仓库找到该模块,依赖包的源代码由github托管,如果项目的子包想被单独引用,则需要通过单独的init go。mod文件进行管理,下面是依赖的原生sdk版本
module example.com/foobar
go 1.16
require (
example.com/apple v0.1.2
example.com/banana v1.2.3
example.com/banana/v2 v2.3.4
example.com/pineapple v0.0.0-20190924185754-1b0db40df49a
)
exclude example.com/banana v1.2.4
replace example.com/apple v0.1.2 => example.com/rda v0.1.0
replace example.com/banana => example.com/hugebanana
工具Go get
go get是Golang自带的包管理工具,用于下载、安装、更新go语言的第三方包和项目。它可以从远程源自动下载并安装对应的包和依赖,而无需用户手动下载和安装,使得在 Golang 中开发更加方便快捷。
格式: go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]
| 参数 | 用法说明 |
|---|---|
| -d | 只下载,而不执行创建、安装 |
| -t | 同时下载命令行指定包的测试代码 |
| -u | 在线下载更新指定的模块(包)及依赖包(默认不更新已安装模块),并创建、安装 |
| -v | 打印出所下载的包名 |
| -insecure | 只下载,而不执行创建、安装 |
| -fix | 允许命令在非安全的scheme(如HTTP)下执行get命令 |
| -f | 忽略掉对已下载代码包的导入路径的检查 |
| -x | 打印输出,get 执行过程中的具体命令 |
工具Go mod
- 使用
go env命令可以查看你的Go Modules是否开启。 - 初始化Go Modules
go mod init [MODULE_PATH][MODULE_PATH]填写的是模块引入路径,你可以根据自己的情况修改路径 go get [MODULE_PATH]拉取指定的依赖库到本地并将它们添加到go.mod中go get -u# 更新现有的依赖go mod tidy# 整理现有依赖go mod download# 下载go.mod文件中指明的所有依赖
小结
本次学习到了Go语言依赖管理的演变过程,通过不同工具的演变一步步完善弊端从而达到想要的开发工具,也学习到了如何使用Go mod这个工具。