Go语言进阶
Goroutine的概念类似于线程,线程可以跑多个协程,协程的栈在KB级别,线程的栈在MB级别。
CSP(Communicating Sequential Processes (CSP)模型),强调通过通信共享内存而不是通过共享内存实现通信。
创建Channel的方法是make方法,无缓冲通道通过make(chan int)创建,有缓冲通道通过make(chan int,2)创建。Channel类型的定义格式:
ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
其中包括三种类型的定义,分别是T(类型形参)、float64(只发送)和int(只接收),"<-"是可选的,不指定则为双向,可以接收数据,也可以发送数据。 并发安全Lock()获取临界区资源,进行操作,Unlock()释放临界区资源,相比之下内存冲突大大减少。
Waitgroup可以实现阻塞,完成并发任务的同步。在sync包下。
依赖管理
工程项目不可能基于标准库0-1编码搭建,因此需要管理SDK依赖库。此时我们需要用到Go Module。
Go Module的发展经历了三个形态,分别是GOPATH、Go Vendor、Go Module。
$GOPATH: 包括bin(项目编译的二进制文件)、pkg(编译的中间产物)、src(项目源码),项目代码直接依赖src下的代码,使用go get 下载最新版本的包到src目录下,弊端是如果AB同时依赖于某一pkg,多版本无法控制(类似于conda之于shell的意义)。
GoVendor: 项目目录下增加vendor文件,所有依赖包副本形式在$ProjectRoot/vendor,本质是利用副本来解决多版本的问题。寻址:vendor => GOPATH,弊端:上上游的依赖包多版本无法控制。
Go Module: go.mod文件管理依赖包版本,go.get/go mod定义版本规则,通过工具来管理依赖关系。
三要素:go.mod、Proxy、go get/mod。
module example/project/app #管理依赖基本单元
go 1.16 #原生库
require( example/lib1 v1.0.2 ) #管理单元依赖
依赖配置的语义化版本:${MAJPR}.${MINOR}.${PATCH}
基于commit伪版本(时间戳)其形式为vX.0.0-yyyymmddhhmmss-hash校验码。
incompatible主版本2+模块会在模块路径增加/vN后缀,对于无go.mod文件并且主版本2+的依赖,会+incompatible。
依赖分发的回源:不安全,不稳定,增加托管压力。
变量GOPROXY:GOPROXY="proxy1.cn, proxy2.cn, direct" #direct代表源站。
go get example.org/pkg,@update #默认,@none #删除依赖,@v1.1.2 #tag版本,@23ddf55 #特定commit,@master #最新版本。
go mod中,init为初始化,download为下载模块到本地缓存,tidy增加需要的依赖,删除不必要的。