go module

go module

Go语言的包管理经过了多种工具的演变,之前我们通过配置GOPATH来存放源代码进行包的管理,其实称不上包管理。Go Module 是Go官方为包依赖管理提供的一个解决方案。

Why go mod ?

我们先来看一下之前GOPATH模式的一些缺点:
1.没法在GOPATH工作区以外的地方写代码
2.不能实现依赖的版本化管理

当我们在GOPATH之外创建项目并使用外部依赖时,运行时go会提醒我们找不到导入的包。那我们怎么解决这个问题呢?

我们可以使用一个特殊的文件,使用它指定仓库的规范名称。这个文件可以理解为是GOPATH的一个替代品,在它其中定义了仓库的规范名称,这样go就可以通过这个名称解析源码的导入包的位置。

这个特殊文件就是go.mod,这个文件中规范名称表示的新实体称为Moduel(模块)。

设置方式

因为没有将go mod设置为默认的包管理方式,增加了一个环境变量GO111MODULE来设置:
默认值是auto。

 

GO111MODULE=off 不使用go mod,go 会从 GOPATH 和 vendor 文件夹寻找包。
GO111MODULE=on 使用go mod,go会忽略GOPATH设置,只根据 go.mod 下载依赖。
GO111MODULE=auto 在 $GOPATH/src 外面且根目录有 go.mod 文件时,开启模块支持。

直接在文件中设置

 

export GO111MODULE=on

一个简单的例子

下面我们通过一个完整的例子熟悉一下go mod的使用方法:
随意创建一个目录example,并用go mod init初始化

 

$ mkdir example
$ cd example
$ go mod init example//初始化
go: creating new go.mod: module example//初始化时生成一个go.mod文件

我们发现初始化时生成了一个go.mod文件,来看看这个文件里面有什么

 

//go.mod
  1 module example //声明了module的名字
  2 
  3 go 1.13//golang的版本

创建main.go

 

  1 package main
  2 
  3 import (
  4     "github.com/spf13/viper"//引用了一个本地没有的依赖
  5     "fmt"
  6 )
  7 
  8 func main() {
  9     viper.SetConfigFile("")
 10     fmt.Println("This is an example.")
 11 }

执行go mod tidy,我们看到在go mod模式下自动下载了项目所依赖的相关包

 

$ go mod tidy
go: finding github.com/spf13/viper v1.3.1
go: downloading github.com/spf13/viper v1.3.1
go: finding github.com/hashicorp/hcl v1.0.0
go: downloading github.com/BurntSushi/toml v0.3.1
...

$ ls
go.mod  go.sum  main.go

增加了一个go.sum文件,文件记录的是依赖包和它自身的依赖包的版本记录

 

//go.sum
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
...

我们再来看下go.mod文件

 

  1 module example
  2 
  3 go 1.13
  4 
  5 require github.com/spf13/viper v1.6.2

go会检测main.go里的import语句,并尝试根据go.mod的依赖关系导入第三包。如果发现本地没有,就会从远程拉取,像go get一样。当go module下载了远程包后,同时会自动更新go.mod。

如上面追加了require github.com/spf13/viper v1.6.2。require后面跟依赖包名版本号

go.mod文件

go.mod文件还可以指定要替换和排除的版本,命令行会自动根据go.mod文件来维护需求声明中的版本。如果想获取更多的有关go.mod文件的介绍,可以使用命令go help go.mod
文件的每行都有一条指令,由一个动作加上参数组成。例如:

 

//go.mod
module my/example

require other/thing     v1.0.2
require new/thing       v2.3.4
exclude old/thing       v1.2.3
replace bad/thing       v1.4.5  => good/thing v1.4.5

上面的三个动词require,exclude,replace分别表示:项目需要的依赖包及版本、排除某些包的特定版本、取代当前项目中的依赖包。

相同动作的命令可以放到括号中,例如:

 

require (
    new/thing v2.3.4
    old/thing v1.2.3
)

注意:一些国内无法访问的依赖,可以用replace替换成其他库:

 

replace golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0

go mod命令的使用

 

download    下载依赖包到本地缓存目录
edit        编辑go.mod文件
graph       打印模块依赖图
init        在当前文件夹下初始化一个新的module, 创建go.mod文件
tidy        增加丢失的module,去掉未使用的module
vendor      将依赖复制到vendor下
verify      校验依赖
why         解释为什么需要依赖

简单介绍一下几个重要的命令:

go mod init:上面的例子我们知道这个命令会初始化目录并创建一个go.mod文件,当然也可以手动创建go.mod文件,然后包含一些module声明,这样就比较麻烦。使用这条命令时,go.mod文件不能提前存在。

go mod download:可以下载所需的依赖,自动下载到$GOPATH/pkg/mod中,并且会把所有的包都打上版本号。其他项目也可以用缓存的module。

go mod tidy:它会添加确实的模块并移除不需要的模块,执行后生成go.sum文件。go mod tidy还可以用来解决依赖包冲突问题。

go mod verify:这个命令会检查当前模块的依赖是否已经存储在本地下载的源代码缓存中,以及检查自从下载下来是否有修改。如果所有的模块都没有修改,那么会打印all modules verified,否则会打印变化的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值