这是我参与「第五届青训营」伴学笔记创作活动的第 2天
Go 语言进阶 - 工程进阶
并发编程
Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。
goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。
goroutine 语法格式:
go 函数名( 参数列表 )
通道(channel)
通道(channel)是用来传递数据的一个数据结构。分为有/无缓存通道
通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。
ch <- v // 把 v 发送到通道 ch
v := <-ch // 从 ch 接收数据
// 并把值赋给 v
声明一个通道很简单,我们使用chan关键字即可,通道在使用前必须先创建:
ch := make(chan int[,size])
注意:默认情况下,通道是不带缓冲区的,当设置大小时为有缓存通道。发送端发送数据,同时必须有接收端相应的接收数据。
Go 遍历通道与关闭通道
Go 通过 range 关键字来实现遍历读取到的数据,类似于与数组或切片。格式如下:
v, ok := <-ch
如果通道接收不到数据后 ok 就为 false,这时通道就可以使用 close() 函数来关闭。
func cal() {
src := make(chan int)
dest := make(chan int, 3)
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
go func() {
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
fmt.Println(i)
}
}
计数器(WaitGroup)
package main
import (
"fmt"
"sync"
)
func main() {
group := sync.WaitGroup{}//1.设置计算器
group.Add(5)//2.设置计数器的大小为5
for i := 0; i < 5; i++ {
go func(j int) {
hellow(j)
group.Done()//3.完成减一
}(i)
}
group.Wait()//阻塞直到一
}
func hellow(j int) {
fmt.Println(j)
}
依赖管理
GOPATH
最初的时候Go语言所依赖的所有的第三方库都放在 GOPATH 这个目录下面。但是这有一个缺点就是同一个库只可以保存一个版本的代码,导致不同项目无法实现多版本控制
Go Vendor
Go Module
go module 是Go语言从 1.11 版本之后官方推出的版本管理工具,并且从 Go1.13 版本开始,go module 成为了Go语言默认的依赖管理工具。
依赖管理三要素 1.配置文件,描述依赖 go.mod 2.中心仓库管理依赖库 Proxy 3.本地工具 go get/mod
其中go.mod文件记录了项目的所有依赖信息,其结构大致如下:
module main.go
go 1.13
require ( github.com/astaxie/beego v1.12.0 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect )
其中,module 为 go.mod 文件所属的包,require 为项目所依赖的包及版本号,indirect 表示间接引用。
GOPROXY
由于日常开发中直接使用版本管理仓库会有很多问题,如:
- 无法保证构建的稳点性(仓库作者修改了仓库)
- 无法保证项目依赖性
- 增加第三方的压力
所以出现了proxy