GO语言进阶之依赖| 青训营

103 阅读2分钟

二、GO语言进阶之依赖

1.并发指的是多线程程序在一个核的CPU上运行;

  并行指的是多线程程序在多个核的CPU上运行。

go语言就能充分的发挥多核优势,处理并行,达到高效运行。

协程是用户态,为轻量级的线程,KB级别;

线程是内核态,线程可以跑多个协程,MB级别。

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

根据这个程序的运行结果,我们能够很清晰的看出来线程的并发,执行的顺序是未知的。

因此更加提倡的是通过通信共享内存,而不是通过共享内存而实现通信。

创建通道的语法如下:

    make(chan int) 无缓冲通道

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

为了保证并发的安全,提出了并发安全锁的概念,能够确保语句都能被执行。

2.依赖管理:

    对于一些简单的语句或者是单体函数,我们可以通过依赖原生的SDK实现;但实际上我们遇到的工程往往会比较复杂,不可能简单的基于标准库0-1编码搭建,更多的是关注业务逻辑的实现,而其他的涉及框架、日志、driver、以及collection等一系列依赖都会通过sdk的方式引入,这样对依赖包的管理就显得尤为重要。

    go的依赖管理主要经历了3个阶段,分别是GOPATH、Go Vender、Go Module。

GOPATH:

    GOPATH是Go语言支持的一个环境变量,value是GO项目的工作区,其目录中的src存放的是Go项目的源码,pkg中存放的是编译的中间产物,可以加快编译的速度,bin中存放的是Go项目编译生成的二进制文件。

    GOPATH管理存在着弊端,在GOPATH管理模式下,如果多个项目依赖同一个库,则依赖该库是同一份代码,所以不同项目不能依赖同一个库的不同版本,这显然不能满足项目的依赖需求。因此,产生了Go Vender。

Go Vender:

    Vender是当前项目中的一个目录,存放了当前项目依赖的副本,在Vender机制下,如果当前目录存在Vender目录,优先使用该目录下的依赖,如果依赖不存在,再去从GOPATH中去寻找。但是,Vender无法很好解决依赖包的版本变动问题和一个项目依赖同一个包的不同版本的问题。因此,Go Module就应运而生了。

Go Module:

    是官方推出的依赖管理系统,解决了之前依赖管理系统存在的注入无法依赖同一个库的多个版本等问题,一般读为go mod。通过go.mod文件管理依赖包版本,通过go get指令工具管理依赖包。

    go mod为了方便管理定义了版本规则,分为语义化版本和基于commit伪版本,不同的MAJOR版本表示是不兼容的API。所以即使是同一个库,MAJOR版本不同也会被认为是不同的模块。

    在语义化版本中,MINOR版本一般是新增函数或功能,向后兼容;而PATCH版本一般是修复bug。

依赖管理三要素:

(1)配置文件、描述依赖 go.mod

(2)中心仓库管理依赖库 Proxy

(3)本地工具 go get/mod

依赖标识:[Module Path] [Version/Pseudo-version]

Go Proxy:

    其作用是一个服务站点,可以解决依赖在github上会产生的种种问题。Proxy会缓存源站中的软件内容,缓存的软件版本不会改变,并且在源站软件删除之后依然可用,实现了不可变和可获得的依赖分发。

    GOPROXY="proxy1.cn,proxy2.cn,direct"

    GOPROXY是一个站点URL列表,用direct表示的是源站,整体的依赖寻址路径,会优先从proxy1下载依赖,如果proxy1不存在,在proxy2中下载,如果还不存在就从源站中直接下载。

思考:go语言的依赖管理相较于其他语言有什么不一样的地方? 通过学习本章内容,我总结了以下几点:

  1. 单一的依赖路径:在 Go 中,所有的代码包依赖都必须放置在一个单一的路径下。这个路径通常是 $GOPATH/src 目录。这种方式保持了代码包的一致性和可维护性。
  2. 自包含的代码包:Go 语言的代码包(模块)是自包含的,即每个代码包都包含了自己的依赖信息。这意味着您只需要导入一个代码包,而不需要考虑它的依赖如何管理。
  3. 无需版本文件:与其他语言的一些依赖管理工具不同,Go 不需要一个单独的版本文件来指定依赖项。每个代码包都有一个唯一的引用路径,版本信息直接体现在引用路径中。
  4. Go Modules:从 Go 1.11 开始,Go 引入了 "Go Modules" 的概念,它是 Go 官方提供的用于依赖管理的解决方案。使用 Go Modules 可以更方便地管理项目的依赖关系,通过在项目中的 go.mod 文件中列出依赖项来实现。它支持语义化版本控制(Semantic Versioning)。
  5. 隐式下载:在 Go 语言中,当您首次导入一个新的代码包时,Go 工具会自动下载该代码包及其依赖,并将其放在指定的缓存目录中。
  6. 集成在工具链中:Go 的依赖管理功能是集成在 Go 工具链中的,不需要额外的依赖管理工具。