这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
前言
复习Go语言的进阶和依赖管理,为开发大项目做好准备
语言进阶
1.高并发
Go语言的高并发性质会导致输出和想象的不一致,需要进行进一步优化,举个例子:
package main
import (
"fmt"
"time"
)
func hello(i int) {
println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRoutine(){
for i:= 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second)
}
func main() {
HelloGoRoutine()
}
2.并发安全
类似于操作系统中生产者消费者的模型的Go语言版,如果不对变量添加Lock,最终结果和预期会有很大区别。
var (
x int 64
lock sync.Mutex
)
func addWithLock(){
for i:=0; i < 2000; i++ {
lock.Lock()
x += 1
lock.Unlock()
}
}
func addWithoutLock() {
for i:=0; i < 2000; i++{
x += 1
}
}
func Add() {
x = 0
for i:= 0; i < 5; i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("WithoutLock", x)
x = 0;
for i:= 0; i < 5; i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("WithLock:", x)
}
上述代码没有加Lock结果是一个随机数(反正不等于10000就对了)
只有添加Lock结果才为10000
依赖管理的三种模式
GOPATH模式
$GOPATH:项目根路径 本质上为Go语言支持的一个环境变量,包含 bin,pkg,src三部分
特点:
- 项目代码直接依赖src下的代码
- go get 下载最新版本的包到src目录下
缺点 : 无法支持package的多版本控制
Go Vendor
通过本地化构建的方式在每个项目下都创建一个vendor目录,每个项目所需要的以来都会下载到自己的vendor目录下。在使用包时,会先从当前项目下的vendor目录查找,然后再从GOPATH中查找。
所依赖包副本形式放在 $ProjectRoot/vendor
寻址方式; vendor => GOPATH
优点 : 解决了多个项目需要同一个package的冲突问题。
缺点 :
- 无法控制依赖的版本
- 更新项目可以出现依赖冲突,导致编译出错
Go Module
- 通过 go.mod文件来管理依赖包的版本
- 通过 go get/go mod 指令工具管理依赖包
依赖管理三要素
- 配置文件,描述依赖
go.mod - 中心仓库管理依赖库
Proxy - 本地工具
go get/mod
go.mod配置
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
结束语
青训营的课程干货很多,刚学完没过几天就快忘光了,还需要定时的去复习并且复现代码,这样记忆才会更加深刻。