Go语言工程进阶(青训营)

21 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 2天

Go 语言进阶 - 工程进阶

并发编程

image-20230116191144331

Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。

goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。

goroutine 语法格式:

go 函数名( 参数列表 )

通道(channel)

通道(channel)是用来传递数据的一个数据结构。分为有/无缓存通道

image-20230116193543893

通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。

ch <- v    // 把 v 发送到通道 ch
v := <-ch  // 从 ch 接收数据
           // 并把值赋给 v

声明一个通道很简单,我们使用chan关键字即可,通道在使用前必须先创建:

ch := make(chan int[,size])

注意:默认情况下,通道是不带缓冲区的,当设置大小时为有缓存通道。发送端发送数据,同时必须有接收端相应的接收数据。

image-20230116193233920

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

image-20230116195551934

依赖管理

image-20230116200920302

image-20230116200939951

GOPATH

最初的时候Go语言所依赖的所有的第三方库都放在 GOPATH 这个目录下面。但是这有一个缺点就是同一个库只可以保存一个版本的代码,导致不同项目无法实现多版本控制

Go Vendor

image-20230116201316641

image-20230116201437310

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

image-20230116205124697

由于日常开发中直接使用版本管理仓库会有很多问题,如:

  • 无法保证构建的稳点性(仓库作者修改了仓库)
  • 无法保证项目依赖性
  • 增加第三方的压力

所以出现了proxy