Linux系统环境go安装和使用go module

本月初Go1.13终于发布,go mod代码管理工具也正式转正。本篇也是记录Go1.13版本在Linux系统的环境搭建和使用go mod工具。

  1. Linux发行版:CentOS7 64
  2. Go安装版本:go1.13.linux-amd64

目录

Go环境安装

使用go mod

go.mod版本管理文件


Go环境安装

  • 官网下载Linux系统对应的安装包
  • 解压安装包到/usr/local/目录下面
tar -zxvf go1.13.linux-amd64.tar.gz -C /usr/local/
  • 把/usr/local/go/bin路径添加到环境变量PATH中
  1. #通过修改.bashrc文件:
  2. vim ~/.bashrc
  3. #在最后一行添上:
  4. export PATH=/usr/local/go/bin:$PATH
  5. #生效方法:(有以下两种)
  6. #1、关闭当前终端窗口,重新打开一个新终端窗口就能生效
  7. #2、输入“source ~/.bashrc”命令,立即生效
  8. #有效期限:永久有效
  9. #用户局限:仅对当前用户
  • 到目前为止算是安装完成,可以使用go命令。比如go env:查看go环境。

这里有2个路径需要明白:

1.GOROOT就是Go安装路径。已经设置好了不需要在设置。
2.GOPATH就是依赖包的安装路径。设置了默认路径/root/go,如果想修改,可以参考上面步骤为GOPATH添加新的路径。

  • Go1.13为环境变量GOPROXY设置了默认路径:https://proxy.golang.org,direct。但是由于某些因素,这个使用不了,你懂的。所以七牛云为中国的gopher提供了一个免费合法的代理goproxy.cn,其已经开源。只需一条简单命令就可以使用该代理:
go env -w GOPROXY=https://goproxy.cn,direct

使用go mod

在不使用go mod情况下,我们的项目必要放在GOPATH路径下(如果不是工程文件,只是一个简单的main.go文件则不需要设置,直接编译运行即可),不然会在代码中 import “包路径” 会出现问题。但是引入go module管理包,就不要设置GOPATH包含次项目路径了。

接下来我们就来看看如何使用go mod来方便的管理各种包。

  • 初始化。在非GOPATH路径创建项目,比如hello。启动gomod特性:
go mod init 目录名

注意:必须进入项目目录(如hello),目录名是当前所在的项目目录名字。执行成功,生成go.mod文件,有点类似Git初始化,请参考Git学习笔记

  • 初次使用。比如代码中使用了GitHub某个包,这里测试使用本人G站上一个测试包。本地代码如下:
  1. package main
  2. import (
  3. api "github.com/tuweiguang/GoTestLib/api"
  4. )
  5. func main() {
  6. api.MyApi()
  7. }
  1. [root@localhost hello]# go run test.go
  2. go: finding github.com/tuweiguang/GoTestLib v0.0.5
  3. go: downloading github.com/tuweiguang/GoTestLib v0.0.5
  4. go: extracting github.com/tuweiguang/GoTestLib v0.0.5
  5. this is MyApi
  6. this is MyApi2
  7. this is MyApi3
  8. this is MyApi4
  9. this is MyApi5
  10. this is MyApi6
  11. [root@localhost hello]# ls
  12. go.mod go.sum test.go

如何导入当前项目中别的包?
使用了 go mod 后所有的 import path 都得以 module path 开头,当前工作目录的话就以go.mod文件中定义模块名字路径开头。假如在hello目录下新创建一个包tool,在test.go中若要使用,则import "hello/tool"。

第一次运行结果可以看出,go编译器发现没有github.com/tuweiguang/GoTestLib/api包,则通过goproxy.cn代理去GitHub网站去拉去GoTestLib包,并且包的下载位置在

GOPATH/pkg/mod/github.com/tuweiguang/!go!test!lib@v0.0.5

这也是为什么必要设置GOPATH的原因。还有几点说明一下:

1.go mod下载的位置和go get下载的位置不一样,go get是在GOPATH/pkg/mod/...路径下。
2.上面包名后面v0.0.5是包的版本号,如果依赖包没有tag号,会类似v0.0.0-20190906040814-a95bafec6648。
3.第一次运行下载是下载GoTestLib包的最新版本,如果想指定版本,下面会介绍。
4.go.sum文件是校验文件,是校验下载的包确实正确没有被别人篡改过。
5.若再次运行,将不再下载GoTestLib包,因为刚才已经下载了。
6.go.mod文件也会增加一行:require github.com/tuweiguang/GoTestLib v0.0.5 // indirect ,这个等会下面再说。

  • 检查依赖包有没有更新版本。输入以下命令:
  1. [root@localhost hello]# go list -m -u all
  2. hello
  3. github.com/tuweiguang/GoTestLib v0.0.5

表示当前依赖的包GoTestLib是最新版,如果有最新版会出现(但是有时会检测不到):

  1. go: finding github.com/tuweiguang/GoTestLib latest
  2. GoTestApi
  3. github.com/tuweiguang/GoTestLib v0.0.5
  • 更新依赖包。这里只介绍2种更新:

1.更新到指定版本。
2.更新到当前最新修订版版本。

  1. [root@localhost hello]# go run test.go //更新前
  2. this is MyApi
  3. this is MyApi2
  4. this is MyApi3
  5. this is MyApi4
  6. this is MyApi5
  7. this is MyApi6
  8. [root@localhost hello]# go get github.com/tuweiguang/GoTestLib@v0.0.6 //指定版本,注意最开始测试最新版本是v0.0.5,v0.0.6是刚才才加的
  9. go: finding github.com/tuweiguang/GoTestLib v0.0.6
  10. go: downloading github.com/tuweiguang/GoTestLib v0.0.6
  11. go: extracting github.com/tuweiguang/GoTestLib v0.0.6
  12. build _/root/go/pkg/mod/github.com/tuweiguang/_go_test_lib@v0.0.6/api: cannot find module for path _/root/go/pkg/mod/github.com/tuweiguang/_go_test_lib@v0.0.6/api
  13. [root@localhost hello]# go run test.go //更新后
  14. this is MyApi
  15. this is MyApi2
  16. this is MyApi3
  17. this is MyApi4
  18. this is MyApi5
  19. this is MyApi6
  20. this is MyApi7
  1. [root@localhost tuweiguang]# pwd
  2. /root/go/pkg/mod/github.com/tuweiguang
  3. [root@localhost tuweiguang]# ls
  4. !go!test!lib@v0.0.5 !go!test!lib@v0.0.6

通过上面测试,更新了指定版本,也下载了相应版本依赖包。再看看go.mod和go.sum文件:

  1. [root@localhost hello]# cat go.sum
  2. github.com/tuweiguang/GoTestLib v0.0.5 h1:EC5pWmPdQbXPB7qUkI18rvwKRSk8Yp8MGxD6qDwNUIs=
  3. github.com/tuweiguang/GoTestLib v0.0.5/go.mod h1:Oeto69u+Bjg5iL6sEf1GguoQ85Yrv/YHiVZGXOZq7HU=
  4. github.com/tuweiguang/GoTestLib v0.0.6 h1:l/uLGgnp+90T6SVCZ6qhvajjbAEmlF01sPeOjv37evI=
  5. github.com/tuweiguang/GoTestLib v0.0.6/go.mod h1:Oeto69u+Bjg5iL6sEf1GguoQ85Yrv/YHiVZGXOZq7HU=
  6. [root@localhost hello]# cat go.mod
  7. module hello
  8. go 1.13
  9. require github.com/tuweiguang/GoTestLib v0.0.6

go.sum文件新增了依赖包GoTestLib版本v0.0.6校验,go.mod文件指定依赖包版本由require github.com/tuweiguang/GoTestLib v0.0.5 // indirect 变为 require github.com/tuweiguang/GoTestLib v0.0.6。

  • 清空依赖包。将GOPATH/pkg/mod里面下载所有依赖包全部删除,下次运行程序,会重新下载最新的依赖包,这里就不测试了。
  • 将hello项目移到GOPATH/src也可以正常执行。

go.mod版本管理文件

从上面例子也看到了,go.mod文件管理当前所使用的依赖包版本,go mod提供了module, require、replace和exclude 四个命令选项。

1.module 选项指定包的项目的名字(路径)。
2.require 选项指定当前使用的依赖包。
3.replace 选项将依赖包替换依赖包。
4.exclude选项将忽略依赖包。

replace测试如下:

  1. [root@localhost hello]# go run test.go
  2. this is MyApi
  3. this is MyApi2
  4. this is MyApi3
  5. this is MyApi4
  6. this is MyApi5
  7. this is MyApi6
  8. this is MyApi7
  9. [root@localhost hello]# cat go.mod
  10. module hello
  11. go 1.13
  12. require github.com/tuweiguang/GoTestLib v0.0.6
  13. [root@localhost hello]# go mod edit -replace github.com/tuweiguang/GoTestLib@v0.0.6=github.com/tuweiguang/GoTestLib@v0.0.5
  14. [root@localhost hello]# cat go.mod
  15. module hello
  16. go 1.13
  17. require github.com/tuweiguang/GoTestLib v0.0.6
  18. replace github.com/tuweiguang/GoTestLib v0.0.6 => github.com/tuweiguang/GoTestLib v0.0.5
  19. [root@localhost hello]# go run test.go
  20. this is MyApi
  21. this is MyApi2
  22. this is MyApi3
  23. this is MyApi4
  24. this is MyApi5
  25. this is MyApi6

exclude测试如下:

  1. [root@localhost hello]# go run test.go
  2. this is MyApi
  3. this is MyApi2
  4. this is MyApi3
  5. this is MyApi4
  6. this is MyApi5
  7. this is MyApi6
  8. [root@localhost hello]# go mod edit -exclude github.com/tuweiguang/GoTestLib@v0.0.5 //忽略v0.0.5版本
  9. [root@localhost hello]# cat go.mod
  10. module hello
  11. go 1.13
  12. require github.com/tuweiguang/GoTestLib v0.0.6
  13. replace github.com/tuweiguang/GoTestLib v0.0.6 => github.com/tuweiguang/GoTestLib v0.0.5
  14. exclude github.com/tuweiguang/GoTestLib v0.0.5
  15. [root@localhost hello]# go run test.go
  16. this is MyApi
  17. this is MyApi2
  18. this is MyApi3
  19. this is MyApi4
  20. this is MyApi5
  21. this is MyApi6

虽然执行忽略v0.0.5版本,但是没有起到效果。再看:

  1. [root@localhost hello]# go mod edit -exclude github.com/tuweiguang/GoTestLib@v0.0.6 //忽略v0.0.6版本
  2. [root@localhost hello]# cat go.mod
  3. module hello
  4. go 1.13
  5. require github.com/tuweiguang/GoTestLib v0.0.6
  6. replace github.com/tuweiguang/GoTestLib v0.0.6 => github.com/tuweiguang/GoTestLib v0.0.5
  7. exclude (
  8. github.com/tuweiguang/GoTestLib v0.0.5
  9. github.com/tuweiguang/GoTestLib v0.0.6
  10. )
  11. [root@localhost hello]# go run test.go
  12. go: hello() depends on excluded github.com/tuweiguang/GoTestLib(v0.0.6) with no newer version available

执行忽略v0.0.6,运行出错,所以起到效果了。所以要想忽略哪个版本,那个版本必须是replace后面跟的版本,否则像第一个测试没有起到效果

不是必须说需要go mod命令来修改,也可以通过手动修改go.mod文件。其他的选项就不测试了。


参考文章:

【煎鱼大佬对goproxy.cn作者@盛傲飞 在Go夜读关于《Go Modules、Go Module Proxy 和 goproxy.cn》技术分享】https://github.com/EDDYCJY/blog/blob/master/talk/goproxy-cn.md

评论 (2)

  • wridway Reply

    Nov 17 2022 05:36 am
  • fravabank Reply

    May 31 2022 03:08 am

发表评论