go协程 和 go module
go 协程
创建协程
只需要加个go再写个函数体就好了
package main
import (
"fmt"
"time"
)
func hello(i int) {
println("hello goroutine" + fmt.Sprint(i))
}
func main() {
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second)
}
协程通信
CSP(Communicating Sequential Processes)
go提供了通信和共享内存两种方式共享内存,但是go提倡通过通信共享内存而不是通过共享内存实现通信。
示例代码
package main
func CalSquare() {
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 {
println(i)
}
}
func main() {
CalSquare()
}
Channel
make(chan 元素类型,[缓冲大小])
· 无缓冲通道 make(chan int) (包含int类型的无缓冲通道
· 有缓冲通道 make(chan int,2) (通道容量为2的int类型的有缓冲通道)
并发安全 Lock
锁的声明 lock sync.Mutex
锁的方法 lock() 取得锁,Unlock() 释放锁\
waitGroup
声明 var wg sync.WaitGroup
提供方法 :
Add(delta int) 计数器 +delta
Done() 计数器-1
Wait() 阻塞直到计数器为0
代码示例
package main
import (
"fmt"
"sync"
)
func hello(i int) {
println("hello goroutine" + fmt.Sprint(i))
}
func main() {
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
go func(j int) {
defer wg.Done()
hello(j)
}(i)
}
wg.Wait()
}
Go Module
概述
通过 go.mod 文件管理依赖包版本
通过 go get/go mod 指令工具管理依赖包
依赖管理三要素
- 配置文件 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
依赖配置 - go.mod
依赖标识 : Module Path + Version/Pseudo-version
version :
语义版本 ${MAJOR}.${MINOR}.${PATCH} 如V 1.3.0 不同MAJOR是相隔离的,同MAJOR下不同MINOR是相兼容的,PATCH是版本的修复
基于commit伪版本 版本前缀-时间戳-哈希码 如 v0.0.0-20220401081311-c38fb59326b7
indirect
没有直接依赖则标注 //indirect
如A -> B -> C ,A ->B 直接依赖,A->C间接依赖
incompatible
主版本2+模块会再模块路径增加/vN前缀 如 /v3
对于没有go.mod文件并且主版本 2+的依赖,会加上incompatible后缀
go proxy
确保依赖可靠。
go.mod通过GOPROXY环境变量(url列表,用逗号分割)来控制proxy的配置。查找依赖会优先查找靠前的url。
工具 go get
go get example.org/pkg
选项 :
@update 默认
@none 删除依赖
@(例)v1.1.2 tag版本,语义版本
@(例)23dfdd5 特定的commit
@master 分支的最新commit\
go mod
选项 :
init 初始化,创建go.mod文件
download 下载模块到本地缓存
tidy 增加需要的依赖,删除不需要的依赖