关于Go语言Module的小例子

小例子A

在看两个例子之前,如果你还没有使用go module的经验,请先阅读这里

例子的程序/源代码:https://github.com/gemark/bingwallpapers/releases/tag/v0.1.0

Windows中的目录结构和go.mod写法
假如我编写了个程序,我要调用自定义包(你可以理解外我上传到github.com后,就是第三方依赖了。)
我看很多人纠结的就是什么第三方包,还是自定义包。在没有go module之前,可能第三方包依赖管理不尽人意,毕竟官方也认为干净的依赖更加重要,大不了多拷贝一份不就好了,其实我也是这样觉得的。
那么一个现实的问题就是,我没打算上传呀…那么我这里先举个例子:
1、使用了GO111MODULE=on环境变量后,$GOPATH不再是go build需要考虑的,我们要考虑的是go.mod怎么写

2、假设我的目录结构是这样的:
关于Go语言Module的小例子_第1张图片
D:\go_project\src\BingWallpepers
BingWallpepers.go 是一个package main的主程序。

3、BingWallpepers.go的Import是这样的:
关于Go语言Module的小例子_第2张图片
那么我这里是调用“看起来的第三方包”,实则是我自己的自定义包,那么我的go.mod长啥样呢?
4、主程序的go.mod这样写:
提示:(go.mod这样产生)
go mod init BingWallpapers
go mod init github.com/gemark/bingwallpapers/config
关于Go语言Module的小例子_第3张图片
这样我们就可以不上传到git服务器上了。而使用本地的自定义包。

5、那么我的自定义包的目录结构长啥样呢?
关于Go语言Module的小例子_第4张图片
上面是我 d:\go_project\src\github.com\gemark\bingwallpapers 的目录结构
下面是config和logger目录的结构和分别go.mod的写法
关于Go语言Module的小例子_第5张图片
关于Go语言Module的小例子_第6张图片
实际上这两张图已经说明,这是两个module,如果你要按照原来package的概念来理解就容易误会了。
我们看看config.go和logger.go的package name
config和logger的package name
这两个go文件中,package的名字都是bingwallpapers,不是config也不是logger文件名作为package name。
在使用了GO111MODULE=on后,我们编译go程序的时候,不再是检测$GOPATH(%GOPATH%)了。

甚至我们的程序都可以不在$GOPATH/src目录中,就可以编译。go build/install/run/test 都是去检测当前编译程序目录下的go.mod文件中的内容。

实际上,无论我们团队开发还是个人开发,无论我们的自定义包在本地还是git上我们完全可以将所有的自定义package做成module,我们引入的不在是packages,而是modules。而go module也解决了同一个项目中依赖了不同版本的某个module。
不同版本的我们可以:

import ( 
	rsa1 github.com/rivest/rsa/v1
	rsa2 mit.edu/rivest/rsa/v2
)

import中,package 地址前面的 rsa1 和 rsa2 为别名。


小例子B

这里我们举一个使用golang.org/x/… modules的例子
1、主程序中,我想要调用golang.org/x/crypto… 的模块
关于Go语言Module的小例子_第7张图片
程序中的import是这样的:
关于Go语言Module的小例子_第8张图片
可是我import的就是golang.org/x/crypto …
要知道我大天朝的Q不是开玩笑的,不用ss这类翻Q,要咋办呢?
在上上张图中,go.mod的replace 也可以解决这个问题,通过 => 符号,我们可以指定要替换的地址,可以是网络地址,可以是本地的地址,前面例子A已经说明了。

2、如果使用的第三方包,如github.com上的,我们可以不go get或则git clone,go module可以根据go.mod中的require中指定的mod地址下载,并且是带版本号的,存放在pkg目录中,见下图:
关于Go语言Module的小例子_第9张图片
所以在Go 1.11后,我们应该以module的视角去看package了,而不在是package在我的 $GOPATH/src/… 中了。在开发中,为了可以获取自动提示,我们才需要考虑import的包名是否能对应在 $GOPATH/src/… 中,因为目前无论是windows还是 linux 下的 gocode or YouCompleteMe 工具都需要扫描到对应的目录下的 .go 文件才能正确的获取到如函数签名、包内变量名…etc。我觉得以后可能也会根据当前编辑的.go文件同目录下go.mod中的中require和replace来识别自定义包和第三方包中代码自动完成所需的内容。

你可能感兴趣的:(Go语言)