GOPATH 与 GO Modules

什么是GOROOT

GOROOT 是环境变量,它的值是 Golang 安装包路径

什么是GOPATH

GOPATH 是Golang 1.5版本之前一个重要的环境变量配置,是存放 Golang 项目代码的文件路径。

go env GOPATH

进入GOPATH目录,查看该目录下的所有文件。

go
├── bin
├── pkg
└── src
    ├── github.com
    ├── golang.org
    ├── google.golang.org
    ....

可以看到有三个文件夹。

bin 存放编译生成的二进制文件。比如 执行命令 go get github.com/google/gops,bin目录会生成 gops 的二进制文件。

pkg 其中pkg下面以下三个文件夹。

XX_amd64: 其中 XX 是目标操作系统,比如 mac 系统对应的是darwin_amd64, linux 系统对应的是 linux_amd64,存放的是.a结尾的文件。

mod: 当开启go Modules 模式下,go get命令缓存下依赖包存放的位置

sumdb: go get命令缓存下载的checksum数据存放的位置

因此在使用 GOPATH 模式下,我们需要将应用代码存放在固定的$GOPATH/src目录下,并且如果执行go get来拉取外部依赖会自动下载并安装到$GOPATH目录下。

简单来说,GOPATH模式下,项目代码不能想放哪里就放哪里,哪怕你的学习资料盘满了也不行。

GOPATH 的缺点

胖虎:除了需要指定目录,还有哪些缺点吗?

除了必须指定目录,还是以下三大罪状。

go get 命令的时候,无法指定获取的版本

引用第三方项目的时候,无法处理v1、v2、v3等不同版本的引用问题,因为在GOPATH 模式下项目路径都是 github.com/foo/project

无法同步一致第三方版本号,在运行 Go 应用程序的时候,无法保证其它人与所期望依赖的第三方库是相同的版本。

为什么需要Go Modules

难道就没有解决办法了吗?我墙裂要求官方,实现存放项目路径自由和不同版本的管理。

在go 1.11 官方出手了推出了 Go Modules, 通过设置环境变量 GO111MODULE 进行开启或者关闭 go mod 模式。

auto 自动模式,当项目根目录有 go.mod 文件,启用 Go modules

off 关闭 go mod 模式

on 开启go mod 模式

开启 go mod 模式后,你的项目代码想放哪里就放哪里,你想引用哪个版本就用哪个版本

GOPROXY

我发现一个问题啊,那就是 github 上面有的包下载不下来,是怎么回事呢?

作为开发者基本上都会用到 github 上面的开源仓库,因网络问题,导致有些包是无法下载下来的。不过不用担心,太阳底下无新鲜事,已经现成的Go 镜像站点帮你获取。

环境变量 GOPROXY 就是设置 Go 模块代理的,其作用直接通过镜像站点来快速拉取所需项目代码。

常见代理配置

阿里云

https://mirrors.aliyun.com/goproxy/

七牛云

https://goproxy.cn,direct

执行命令:

go env -w GOPROXY="https://goproxy.cn,direct" 

新创建一个空目录test_mod,进入该目录,执行命令

//test_mod 为项目名称
go mod int test_mod

会在根目录生成一个 go.mod 文件,内容如下:

module test_mod

go 1.17

如果想引入第三方网络包,在该项目目录执行 go get 仓库地址。比如引入定时任务:

go get github.com/robfig/cron/v3

go.mod 会变成为, indirect 代表是间接依赖,因为当前项目是空的,所以并没有发现这个模块的明确引用。

module test_mod

go 1.17

require github.com/robfig/cron/v3 v3.0.1 // indirect

并且也会新增一个go.sum文件, 它的作用是保证项目所依赖的模块版本,不会被篡改。

github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=

注意此时,我们的项目是没有任何go代码文件的,现在只有 go.mod 和 go.sum 两个文件

go mod tidy

如果我们 go.mod 导入了第三方包,但项目代码中我不用,就是玩。领导发现后,不小心一个 go mod tidy 命令,直接把你回到解放前

观察 go.mod 会发现已经没有了这串神秘代码

require github.com/robfig/cron/v3 v3.0.1 // indirect

机智的你,可能已经猜到了,go mod tidy 就是去掉go.mod文件中项目不需要的依赖。

go mod edit

如果引入的开源项目的源代码,别人删除了怎么办呢?

自己本地新开发项目代码,还没有推送到远程仓库,其他项目要引用怎么办?

不要慌,学长有两个锦囊妙计供你使用,你可按照自己喜好按需使用。

方法1

执行命令:

go mod edit -replace [old git package]@[version]=[new git package]@[version]

例如:

go mod edit -replace github.com/bndr/gojenkins=github.com/Bpazy/gojenkins@latest

执行后 ,会发现 go.mod 文件最后有一串神秘代码

replace github.com/bndr/gojenkins => github.com/Bpazy/gojenkins v1.0.2-0.20200708084040-3655c428bba9

方法2

简单粗暴,直接修改go.mod文件,在go.mod文件最后添加以下神秘代码

replace github.com/bndr/gojenkins => github.com/Bpazy/gojenkins v1.0.2-0.20200708084040-3655c428bba9

即可完美解决此问题,replace 还有一个隐藏的秘密,那就是可引入本地项目代码

replace github.com/bndr/gojenkins => ../gojenkins

总结

猜你喜欢

转载自blog.csdn.net/zhanglixin999/article/details/129793785