Go语言进阶与依赖管理

86 阅读2分钟

1 语言进阶

1.1 并发和并行

并发:多线程程序在一个核的cpu上运行,交替使用;
并行:多线程程序在多个核的cpu上运行,同时进行。

1.2 Goroutine—协程

协程:用户态,轻量级线程,栈KB级别。
线程:内核态,线程跑多个协程,栈MB级别。

1.3 CSP(communicating Sequential Processes)

提倡通过通信共享内存而不是通过共享内存而实现通信。

image.png

使用make(chan元素类型,[缓冲大小])

  • 无缓冲通道:make(chan int)
  • 有缓冲通道:make(chan int,2)

image.png

// 例子:
func CalSquare(){
    src := make(chan int)
    dest := make(chan int, 3)
    go func(){   // A
        defer close(src)
        for i := 0; i<10;i++{
            src <- i
        }
    }()
    go func(){    // B
        defer close(dest)
        for i := range src{
            dest <- i
        }
    }()
    for i := range dest {    // M
        println(i)
    }

A子协程发送0~9数字
B子协程计算输入数字的平方
主协程输出最后的平方数

1.4 WaitGroup

计数器:开启协程+1,执行协程-1,主协程阻塞直到计数器为0

image.png

func hello(i int){
    println("hello goroutine : " + fmt.Sprint(i))
}
func ManyGoWait(){
    var lm sync.WaitGroup
    lm.Add(5)
    for i := 0;i<5;i++{
        go func(j int){
            defer lm.Done()
            hello(j)
        }(i)
    }
    lm.Wait()
}

2 依赖管理

2.1 Go依赖管理演进

GOPATH -> Go Vendor -> Go Module
不同环境(项目)依赖的版本不同

2.1.1 GOPATH

在GOPATH下:

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

项目代码直接依赖src下的代码
go get 下载最新版本的包到src目录下
弊端:当项目A和B依赖于某一个package的不同版本时,无法实现package的多版本控制

2.1.2 Go Vendor

项目目录下增加vendor文件,所有依赖包副本形式放在$ProjectRoot/vendor
依赖寻址方式: vendor => GOPATH
通过每个项目引入一份依赖的副本,解决了多个项目需要同一个package依赖的冲突问题。

image.png 弊端:无法控制依赖的版本。
更新项目又可能出现依赖冲突,导致编译出错。

2.1.3 Go Module

  • 通过go.mod文件管理依赖包版本
  • 通过go get/go mod指令工具管理依赖包
  • 目标:定义版本规则和管理项目依赖关系

2.2 依赖管理三要素

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

2.3.1 依赖配置—go.mod

image.png

2.3.2 依赖配置—version

  1. 语义化版本
    V1.3.0、V2.3.0
  2. 基于commit 伪版本 vX.0.0-yyyymmddhhmmss-abcdefgh1234
    v0.0.0-20220401081311-c38fb59326b7
    v1.0.0-20201130134442-10cb98267c6c\
  3. indirect:间接依赖
  4. incompatible:主版本2+模块会在模块路径增加/vN后缀。
    对于没有go.mod文件并且主版本2+的依赖,会+incompatible。

2.3.3 依赖分发—回源

image.png

  • 无法保证构建稳定性,增加/修改/删除软件版本
  • 无法保证依赖可用性,删除软件
  • 增加第三方压力,代码托管平台负载问题
  • 依赖分发—proxy image.png

2.3.4 工具—go get

go get example.org/pkg

  • @update 默认
  • @none 删除依赖
  • @v1.1.2 tag版本,语义版本
  • @23dfdd5 特定的commit
  • @master 分支的最新commit

2.3.5 工具—go mod

go mod:

  • init:初始化,创建go.mod文件
  • download:下载模块到本地缓存
  • tidy:增加需要的依赖,删除不需要的依赖