go的依赖管理及编译
依赖管理工具
为什么go需要依赖管理工具
早期go下载的第三方包都在$GOPATH$/src
下,查找时也从$GOPATH$/src/
中进行查找,如果没有$GOPATH$
则会使用$GOROOT$
。
而在有多个go项目时,同一个包有时会需要不同的版本,早期时go get也没有版本约束,此时这些包如果都在一个目录下,就不方便进行下载和查找了。
因此就需要依赖管理工具。
go有哪些依赖管理工具
关于每个管理工具网上都有详细的教程,这里就简单的进行一下说明,旨在进行对比。
godep和vendor
特性
第三方导入路径重写
思想
把所有的依赖包复制到工程代码库中的目录里,然后使用工程内部的依赖包所在目录来重写所有的导入路径
缺点
通常,新的导入路径由于要加上该工程代码库所在的路径,所以重写后的路径会变成非常的长,不易于一目了然。
优点
- 将依赖的源代码都导入到一个单独的工程代码库里,可以更容易的重新构建工程。
- 依旧支持go get找到每个包,并将其保存到工程里正确的目录中
gb
特性
gb背后的原理源自理解到 Go 语言的 import 语句并没有提供可重复构建的能力。
import语句可以驱动 go get,但是import 本身并没有包含足够的信息来決定到底要获取包的哪个版本。
go get 无法定位待获取代码的问题,才导致 Go 工具在解决重复构建的问题时,不得不使用复杂且难看的方法。
思想
gb既不包装 Go 工具链,也不使用 GOPATH。 gb 基于工程将go工具链工作空间的元信息做替换。
缺点
与go get工具链不兼容,无法用go工具链构建,测试或者获取代码。因此需要进入当前工程目录使用gb命令进行构建
优点
不需要重写导入路径
mod
我认为是最新最常用的依赖管理工具,而且他是官方的依赖管理工具,他使用mod文件进行管理,兼容go工具链,也不需要重写路径,因此接下来专门讲一讲go mod。
go mod
开启go mod
首先,go是可以自主选择是否使用go mod来进行包管理的。
可通过go env |grep MOD
查看是否开启,使用export GO111MODULE="on"
开启,通常在开启时还需要用go env -w GOPROXY="https://goproxy.cn,direct"
来设置为中国代理。
这里需要注意,go规定go.mod是不能存在于GOPATH下的。
这意味着若打开了go mod,就不能把GOPATH和go.mod 设置为同一目录,否则系统会报错$GOPATH/go.mod exists but should not
。
因为如果开启了GO111MODULE,go在编译时就不会去 GOPATH 目录下进行查找了,这里不能自相矛盾。
修改GOPATH示例:export GOPATH=`pwd `
使用go mod
- go mod init `module名`进行初始化
- go mod tidy 自动检测以来包并安装
在goland里使用go mod
- 需要在modules里打开go module intergration来让goland支持go mod
- goland中的GoPath配置仅仅是goland编译时的查找路径,如果在console里使用
go mod tidy
命令来进行包管理,则依旧都是以go env |grep PATH
显示出的GOPATH作为目录的。这意味着goland中的GoPath要包含系统GoPath,否则goland依旧找不到依赖包。
编译
go需要先编译文件,再执行构建后的文件
使用无参数go build
,表示编译当前目录,等同于go build .
,把当前目录下的main文件编译成可执行文件
而后可以使用./可执行文件名
进行执行
go build
后也可以指定具体文件名,或者使用…通配符来表示匹配所有字符串
也可以使用go run 文件名
来一次性编译并执行构建后的程序,go run
命令必须要指定文件名
最后可以使用go clean
来清除可执行文件