Go语言进阶与依赖管理

88 阅读3分钟

Go语言进阶与依赖管理

1语言进阶

1.1Goroutine

Go可以充分发挥多核优势,运行高效

再调用一个函数时候在前面加上“go”就为这个函数创建了一个协程 用time.Sleep(time.Second)来保证子协程执行完之前主协程不退出,用在每一个子协程的后面 代码示例

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)
}

1.2CSP(Communicating Sequential Processes)

Go提倡通过通信共享内存

image.png

Go也保留右图的机制

1.3Channel 创建: make(chan元素类型,[缓冲大小]) 分类:

  • 无缓冲通道(又称同步通道) make(chan int)
  • 有缓冲通道 make(chan int,2)

image.png “同步”解释:发送和接收是同步的

“缓冲”工作:通道容量满了之后,必须有rountine取走数据才可以继续往channel内发送数据(典型的生产消费模型)

Channel的具体使用示例:

  • A子协程发送0~9数字
  • B子协程计算输入数字的平方
  • 主协程输出最后的平方数
func CalSquare(){
    src:=make(chan int)//A与B之间的channel
    dest:=make(chan int,3)//B与主协程之间的channel
    go func(){//创建A协程
        defer close(src)//???????
        for i:=0;i<10;i++{
            src<-i//将生成的数字推入A协程
        }
    }()//?????
    go func(){
        defer close(dest)
        for i:=range src{//B协程从src通道中接受数据
            dest<-i*i
        }
    }()
    for i:=range dest{//主协程从dest通道中接收数据并输出
        //带缓冲的channel可以解决生产与消费速率不同带来的执行效率问题
        //一般来说,消费时是复杂的,更慢
        println(i)
    }
}

1.4并发安全Lock

示例:对变量进行2000次+1操作,要求5个协程并发执行

package main  
  
import (  
"sync"  
"time"  
)  
  
var (  
x int64  
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 addWithoutLock() //5个协程  
}  
time.Sleep(time.Second)  
println("WithoutLock:", x)  
x = 0  
for i := 0; i < 5; i++ {  
go addWithLock()  
}  
time.Sleep(time.Second)  
println("WithLock:", x)  
}  
  
func main() {  
Add()  
}

1.5WaitGroup

func hello(i int){
    Println("hello foroutine :"+fmt.Sprint(i))
}
func HelloGoRoutine(){
    for i:=0;i<5;i++{
        go func (j int){
            hello(j)
        }(i)
    }
    time.Sleep(time.Second)
}
func ManyGoWait(){
    var wg sunc.WaitGroup
    wg.Add( 5)
    for i:=0;i<5;i++{
        go func(j int){
            defer wg.Done()
            hello(j)
        }(i)
        wg.Wait()
    }
}

2依赖管理

背景:

  • 依赖:各种开发包
  • 工程项目不可能基于标准库从头编码搭建

2.1Go依赖管理

演进:

  • GOPATH
  • GoVendor
  • GoModule

2.1.1GOPATH环境变量

GOPATH是我们的工作目录,其中包含的最主要的三个文件是bin,,pkg,src

  • bin 项目编译的二进制文件
  • pkg 项目编译的中间产物,加速编译
  • src 项目源码 项目代码直接以来src下的代码 go get下载最新版本的报道src目录下

GOPATH弊端:无法实现package的多版本控制

image.png

2.1.2Go Vender

image.png Go Vender弊端

image.png

2.1.3Go Module

image.png

2.2依赖管理三要素

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

2.3.1依赖配置-go.mod

image.png

2.3.2依赖配置-version

image.png

2.3.5 依赖分发-回源

image.png

2.3.5依赖分发-Proxy

image.png

2.3.6依赖分发-变量GOPROXY

image.png

2.3.7工具-go get

image.png

2.3.8工具 -go mod

image.png