Go Modules使用

Go Modules使用

Go Modules在Go 1.12版本后默认支持。如果是1.12之前的版本,需要设置一下GO111MODULE环境变量。

1. 为什么要用Go Modules?

在没有Go Modules之前,使用的是GOPATH。在使用GOPATH时,感觉非常不适的是:如果你的工程有自建包,则一定要将工程放到GOPATH下,然后import才能引用到这些包。

helloword
├── code
│   ├── unicode.go
│   └── utf8.go
├── lang
│   ├── ch.go
│   └── es.go
└── main.go

如上图,有一个helloword工程,有两个自建包:codelang,如果想在main.go文件中引用这两个包,必须要将整个helloworld工程放入GOPATH路径下,不然会找不到这两个包,尽管它们在一个工程目录下(Go在编译时默认只会从GOPATH和GOROOT下寻找包)。

还有一点就是第三方包版本管理,GOPATH时期所有的第三方包也都是放在GOPATH路径下的,这个路径对所有的工程是共享的,假设有A,B两个工程,都引用了一个第三方包packageXXX,这时如果A工程突然要用到packageXXX的新版本,这时它将packageXXX包更新,并自已测试通过上线,A工程没事,但B工程却有很大的风险。

				  -------       -------
				 |   A   |     |   B   |
				  -------       -------
                       |         |  
                         |     |    
                            |   
					  ------------
					 | packageXXX |
					  ------------

在1.12版本引入Go Modules后,彻底废弃了GOPATH,通过Go Modules管理的工程不在需要放入GOPATH路径下,而是可以放在任意路径下,并且每个工程引用包都私有化,不再会互相影响,最重要的是操作非常简单。

2. Go Modules使用

还是以上面的helloworld工程为例来一步步展示Go Modules是如何使用的。

首先建立一个工程目录,目录可以放在任意位置:

mkdir helloworld

实现工程,最终的目录结构是:

helloword
├── code
│   ├── unicode.go
│   └── utf8.go
├── lang
│   ├── ch.go
│   └── es.go
└── main.go

工程实现完了,就可以开始编译工程了,这时开始使用Go Modules包工具,首先初始化工程:

go mod init helloworld

helloworld模块名,具体的意义我会在后面详细描述。

执行init命令后,会在helloworld工程下生成一个go.mod文件,这个文件记录了模块名和使用的Go的版本号。

module helloworld

go 1.14

执行go mod vendor将helloworld依赖的第三方工程包全部私有化到本工程的vendor目录下:

go mod vendor

执行完后,会在helloworld目录下生成一个vendor目录,第三方工程包就全部在里面了。同时也会生成一个go.sum文件,这个文件描述了引用的每个第三方包的名称、版本号以及包的md5值。

引用三方包的问题解决了,那Go Modules是如何引用本地包的呢。上面提到过Go编译器会默认从GOPATHGOROOT去寻找包,现在整个工程已经不放在GOPATH路径下了,这时该如何引用本地包?

其实很简单,只需用我们在初始化工程时的模块名再加本地包名即可,举例如下:

helloworld本地包有两个codelang,模块名为helloworld,这时在main.go文件中代码如下:

import (
	"helloworld/code"
	"helloworld/lang"
)

这样就可以成功的引用到本地包。

最后整个工程的目录结构为:

helloworld
├── code
├── lang
├── vendor
├── main.go
├── go.sum
└── go.mod

3 directories, 3 files

3. 模块名的使用方式

上面的示例中,工程目录名和模块名是同一个名字,会认人误以为工程目录名就应该是模块名,但其实两者并没有任何关系。下面看下etcd是如何用Go Modules的。

可以直接看下etcd源码下的go.mod文件,如下:

module go.etcd.io/etcd/v3

go 1.14

require (
	...
)

它在引用它本地包时,代码为:

import (
	"go.etcd.io/etcd/mvcc"
	...
)

猜你喜欢

转载自blog.csdn.net/fengshenyun/article/details/107465685