Go语言进阶与依赖管理 | 青训营笔记

35 阅读3分钟

这是我参与「第五届青训营 」笔记创作活动的第二天

一、Go高性能

1、并发编程

Go语言自带并发编程功能,可以发挥多核优势,使程序高效运行

2、Goroutine

在操作系统中我们学习到了进程与线程的知识,线程是在进程的基础上进一步划分。Go语言为了实现高性能编程,引入了一个新的概念“协程”。一个线程可以跑多个协程,协程为栈KB级别,更加轻量级,用户通过对协程控制可以实现更高效的并发操作。

在Go语言中,创建一个协程是通过go关键字来实现的,go后面跟一个函数即可创建一个新的协程,该函数的执行会在这个协程中进行,与其它协程异步执行。该函数可以是用户事先定义的函数,也可以是一个匿名函数。

main函数本身也算一个特殊的协程,当main函数执行完毕时,所有的协程都会同时关闭,所以在运行协程时要注意在主函数加上一个暂停的语句,或通过WaitGroup来控制。WaitGroup的用法会在后面提及

3、Channel

当多个协程共享一个变量时,会有这么一个问题:如果两个协程同时对一个变量进行操作,那么结果就会有不确定性,从而会影响整个程序的结果。

Go语言为了解决这个问题,提倡使用通信的方法代替共享内存,引入了Channel机制。Channel可以理解为一个通道,这个通道可以是无缓冲区通道,也可以设置n个缓冲区。不带缓冲区的通道在接收信息后必须发出该信息后才能再次接收信息,带x个缓冲区的通道则在通道内有x个消息未被接收时才会停止接收信息。合理使用通道可以有效避免各协程共用变量的冲突问题。

操作:

无缓冲通道:make(chan int)
有x个缓冲区的通道:make(chan int,x)
将值x发送给通道s:s <- x
将通道s中的值发送给值x:x := <- s

4、WaitGroup

main函数运行完毕之前,我们要保证各协程也要运行完毕,否则协程将会被强制关闭。实现这个操作我们可以通过WaitGroup来进行,WaitGroup有以下操作:

wg.Add(x)//计数器加x
wg.Done()//计数器减一
wg.Wait()//等待直到计数器为0

WaitGroup也可以实现各协程之间的串行并行控制,这里不再详述。

二、依赖管理

1、GOPATH

bin:项目编译的二进制文件
pkg:项目编译的中间产物,加速编译
src:项目源码

GOPATH是项目根路径,所有工程代码放在GOPATH/src目录下,故不在GOPATH/src就不能编译,且没有版本控制的概念。

2、vendor

相比GOPATH,在项目下会创建一个vendor目录,每个项目所需的依赖会被下载到该目录下,使用包时优先从当前项目的vendor目录中查找,若找不到再从GOPATH中查找。但其无法控制依赖的版本,且更新项目时可能出现依赖冲突,导致编译出错。

3、Go Module

通过go.mod文件管理依赖包版本,所有依赖的包存放在GOPATH/pkg/mod

go.mod //配置文件,描述依赖
Proxy //中心仓库管理依赖库
go get/mod //本地工具

依赖配置分为两种,其中语义化版本格式为major.minoe.patch,如V1.3.0;基于commit伪版本格式为vX.0.0-yyyymmddhhmmss-abcdefgh1234。同时还有着直接依赖与间接依赖的区别,间接依赖会在版本后加上//indirect的标识。

主版本2+模块会在模块路径增加/vN后缀,如example/lib5/v3 v3.0.2。对于没有go.mod文件并且主版本2+的依赖,会有+incompatible标识