乐趣区

关于golang:简单聊聊-GOPATH-与-Go-Modules

话说胖虎最近招了一个实习生,实习生进来也有一段时间了,天天一个人坐在工位,很少跟四周的共事交换,也不晓得有没有遇到什么问题。

胖虎决定主动出击,简略理解下实习生最近的学习状况,也关怀一下工作是否顺利

什么是 GOROOT

胖虎:来了有几天了,我来验收一下学习的状况吧。先说说什么是 GOROOT 吧

实习生笑道:这个简略啊, 几乎就是送分题啊,学长,GOROOT 是环境变量,它的值是 Golang 安装包门路

胖虎心田 os:这又不是面试造火箭,必定不会尴尬你啊。要是面试问这个问题,算我输。

什么是 GOPATH

胖虎:那 GOPATH 呢?

实习生:GOPATH 是 Golang 1.5 版本之前一个重要的环境变量配置,是寄存 Golang 我的项目代码的文件门路。

如何查看 GOPATH 门路

实习生:在命令控制台输出

go env GOPATH

或者输出:

go env | grep 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 数据寄存的地位

  • src 寄存 golang 我的项目代码的地位

因而在应用 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 模式后,你的我的项目代码想放哪里就放哪里,你想援用哪个版本就用哪个版本,你的地盘,你做主。妈妈再也不必放心你的 F 盘磁盘空间不够用了。

GOPROXY

实习生:学长,我发现一个问题啊,那就是 github 下面有的包下载不下来,是怎么回事呢?

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

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

常见代理配置

  • 阿里云

    https://mirrors.aliyun.com/go…

  • 七牛云

    https://goproxy.cn,direct

执行命令:

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

初始化 Modules

实习生:go mod 既然这么好,那应该怎么应用 go mod 呢?快教教我吧。

基于 go1.17.3 版本

胖虎:咳咳,学长教学工夫开始了,新创建一个空目录 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

总结

疑难

胖虎:最初问下你一个问题吧,go.mod 批改了,要提交到我的项目仓库,那 go.sum 文件要不要一起提交呢?如果不提交会产生什么结果?答复上来明天就让你提前上班。

实习生:……

有违心帮实习生的大佬吗?

以上是明天跟大家分享的内容,如果这篇文章对你有帮忙,辛苦帮忙点个赞,谢谢

文章首发于公众号
微信搜寻公众号 [后端时光] 一起学习成长 !
你必须十分致力,能力看起来毫不费力!

退出移动版