golang包管理问题
初学go, 跟着b站教学配置了GOPATH和GOROOT,其中GOROOT是安装go的路径,GOPATH下放了我第一次建的项目project1
然而刚写了两行代码:
就提示我第一行错了(现在已经解决),报错为
package main is not in GOROOT
奇奇怪怪,后参考go安装以及使用gomod、 goland设置 - 明天OoO你好 - 博客园得知: “默认go会将$HOME/go目录作为gopath,所有项目下载的依赖包都会存放在这个目录下”,但是为什么我的gopath设置了指定位置,还是不行?
解决
好的,现在我想要一个类似于maven的包管理工具,因为gopath有以下特点:1)代码开发必须在go path src目录下,不然有问题;2)依赖手动包管理;3)依赖包没有版本可言
gomod就是一个比较好的包管理工具。现在来使用gomod:go mod使用 - 简书
(1)升级SDK:go module是golang 1.11新特性,在1.12就已经发布了,现在我下的是1.17,不用升级了。
(2)在cmd中查看设置
go env
修改设置
go env -w GOBIN=D:\goSDK\go\bin
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct // 使用七牛云的
(3)新建项目project1,并在项目目录下运行
go mod init project1
这样就创建了go.mod文件。文件一旦创建后,它的内容将会被go toolchain全面掌控,go toolchain会在各类命令(go get、go build、go mod等)修改和维护go.mod文件
go mod tidy
用于删除不用的模块,拉取需要的模块
(4)创建main.go文件,在项目中正常添加依赖
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
正常了,不会再报错
执行 go run main.go 运行代码会发现 go mod 会自动查找依赖自动下载
go module 安装 package 的原則是先拉最新的 release tag,若无tag则拉最新的commit
go 会自动生成一个 go.sum 文件来记录 dependency tree
再次执行脚本 go run main.go发现跳过了检查并安装依赖的步骤。
可以使用命令 go list -m -u all 来检查可以升级的package,使用go get -u need-upgrade-package 升级后会将新的依赖版本更新到go.mod * 也可以使用 go get -u 升级所有依赖
go module与GOPATH冲突问题
当我以为已经解决的时候,发现引自定义的包时还是会报“package is not in GOROOT”问题
原因:
编译器没有去gopath下找包,可能是因为GO111MODULE没有关: gomod 和 gopath 两个包管理方案,并且相互不兼容。在 gomod 模式下,查找包就不会去 gopath 查找,只是 gomod 包缓存在 gopath/pkg/mod 里面。
1)在 gopath 查找包:按照 goroot 和多 gopath 目录下 src/xxx 依次查找。
2)在 gomod 下查找包:解析 go.mod 文件查找包,mod 包名就是包的前缀,里面的目录就后续路径了。
解决方法:把GO111MODULE置为off
go env -w GO111MODULE=off
GO111MODULE
https://www.jianshu.com/p/dca7c631587f
GO111MODULE 有三个值:off, on和auto(默认值)。
GO111MODULE=off,无模块支持,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
GO111MODULE=on,模块支持,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
GO111MODULE=auto,默认值,根据当前目录下是否有 go.mod 文件来判断是否使用 modules 功能
1) 当前目录在GOPATH/src之外且该目录包含go.mod文件,开启模块支持。
2) 当前文件在包含go.mod文件的目录下面。
在使用模块GO111MODULE=on时,GOPATH是无意义的,不过它还是会把下载的依赖存储在$GOPATH/pkg/mod 中,也会把go install 的结果放在 $GOPATH/bin 中。
当modules 功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的module。
go.mod 四个命令
module
语句指定包的名字(路径)require
语句指定的依赖项模块replace
语句可以替换依赖项模块exclude
语句可以忽略依赖项模块
go mod相关知识
go mod常用命令
golang提供了go mod命令来管理包
命令 | 说明 |
---|---|
download | download modules to local cache(下载依赖包) |
edit | edit go.mod from tools or scripts(编辑go.mod) |
graph | print module requirement graph (打印模块依赖图) |
verify | initialize new module in current directory(在当前目录初始化mod) |
tidy | add missing and remove unused modules(拉取缺少的模块,移除不用的模块) |
vendor | make vendored copy of dependencies(将依赖复制到vendor下) |
verify | verify dependencies have expected content (验证依赖是否正确) |
why | explain why packages or modules are needed(解释为什么需要依赖) |