go的包管理
package
go没有命名空间的概念,只有包的概念,每个目录下的package名需要一致,但是不需要跟所在目录名相同:
注意,同级目录下的文件package名不能不一致,否则报错:
不同目录下的包名如果名称一样,可以取别名:
package main
import test "./test"
import test2 "./test2"
func main() {
test.Test()
test2.Test()
}
GOPATH 模式
在没有go mod模式之前,go的包管理需要通过GO_PATH环境变量方式指定目录,并在目录中存放包:
通过 go help gopath 或者go env GOPATH 命令可看到当前go运行时候的环境变量:
Here's an example directory layout:
GOPATH=/home/user/go //gopath变量
/home/user/go/ //存放的目录
src/ //存放的go包
foo/
bar/ (go code in package bar)
x.go
quux/ (go code in package main)
y.go
bin/ //可执行二进制文件
quux (installed command)
pkg/ //编译后的文件
linux_amd64/
foo/
bar.a (installed package object)
我们需要将下载后的包存放到 $GOPATH/src中,即可被go引入:
可看到,虽然goland提示未找到此函数,但是编译后正常运行.
由于GOPATH 包管理起来非常麻烦,所以到后面go官方支持了go module模式
go module模式
GO111MODULE
GO111MODULE是一个环境变量,用于决定go的包管理模式,它有3个值:
1:off 关闭状态,在此状态,编译时只从 GOPATH/src或者vendor目录中寻找依赖
2:on 开启状态,在编译时不会在 $GOPATH/src 中寻找依赖. 将在项目根目录读取 go.mod 文件,同时,依赖包不再存放在 $GOPATH/src 目录,而是存放在 $GOPATH/pkg/mod 目录,多个项目可以共享缓存的 modules.
3:auto 如果目录下存在go.mod文件,则通过2逻辑寻找,否则通过1
go mod init projectName
初始化go项目 ,将生成go.mod文件:
(base) tioncico@appledeMacBook-Pro LearnGoProject % go mod init testProject
go: creating new go.mod: module testProject
go: to add module requirements and sums:
go mod tidy
go mod常用命令
go get url //下载指定的依赖包
go mod init // 初始化 go.mod,将开启 mod 使用
go mod tidy // 添加或者删除 modules,取决于依赖的引用
go mod vendor // 复制依赖到 vendor 目录下
// 其它命令
go mod download // 下载 module 到本地
go mod edit // 编辑 go.mod
go mod graph // 打印 modules 依赖图
go mod verify // 验证依赖
go mod why // 解释依赖使用
例如:
go get github.com/golang/protobuf/proto
go get github.com/golang/protobuf/protoc-gen-go
将生成:
go vendor特性
为了避免项目中的依赖污染,go在1.6开启了vendor目录,每个项目的依赖包都可以放入vendor目录中,互不影响
你可以直接复制包到vendor目录中,也可以通过govendor包管理工具,go mod vendor命令方式复制依赖包到vendor目录中
加载顺序
-
在当前目录下的 vendor 目录查找依赖的 package
-
当前目录不存在 vendor 目录,则去上一级目录寻找
-
重复步骤 2 直到进入 $GOPATH/src 目录
-
没有在 vendor 目录中查找到依赖包,则进入 $GOROOT 目录查找依赖包
-
$GOROOT 目录也没有依赖包,则进入 $GOPATH 目录寻找依赖包
go mod编译模式
在开启go mod后,GOPATH/src 目录下的依赖将是无效的.
通过-mod=flag携带编译参数,选择不同的编译模式:
-mod=readonly
只读模式,如果待引入的 package 不在 go.mod 文件的列表中. 不会修改 go.mod ,而是报错. 此外,若模块的 checksum 不在 go.sum 中也会报错. 这种模式可以在编译时候避免隐式修改 go.mod.
-mod=vendor
mod=vendor 模式下. 将使用工程的 vendor 目录下的 package 而不是 mod cache( GOPATH/pkg/mod) 目录. 该模式下编译,将不会检查 go.mod 文件下的包版本. 但是会检查 vendor 目录下的 modules.txt(由 go mod vendor 生成). 在 go.1.14 及更高版本,若存在 vendor 目录,将优先使用 vendor 模式.
-mod=mod
mod=mod 模式下,将使用 module cache,即使存在 vendor 目录,也会使用 GOPATH/pkg/mod 下的package,若 package 不存在,将自动下载指定版本的 package.
- 本文标签: 编程语言
- 本文链接: https://www.php20.cn/article/324
- 版权声明: 本文由仙士可原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权