在编写复杂一些的Go工程,刚开始对GOROOT,GOPATH,GO111MODULE,go.mod之间用法。
图1
经常会报下面类似错误:
main.go:6:7: cannot find package "chapter2" in any of: /usr/local/go/src/module (from $GOROOT) /home/linux/go/src/module (from $GOPATH)
原因是在GO111MODULE="off"情况下,并且写的代码不在$GOPATH/src下,也就是说下面的main.go不在$GOPATH/src目录下面,同时我想要使用另一个module里面的内容,并且这个module不是标准库,或者说不在GOROOT里会提示类似以上错误。在这种情况下Go只会去找GOROOT目录下或者GOPATH/src目录下。
GOROOT和GOPATH
GOROOT就是go的安装路径,一般要把%GOROOT%/bin要加入到环境变量PATH里(windows环境),%GOROOT%/src目录下一般存放Go的标准库例如fmt,html等。
GOPATH作用:
存放标准库以外的第三方类库
存放自己可复用的代码
目录结构:$GOPATH目录约定有三个子目录
src存放源代码(比如:.go .c .h .s等) 按照golang默认约定,go run,go install等命令的当前工作路径(即在此路径下执行上述命令)。
pkg编译时生成的中间文件(比如:.a)golang编译包时
bin编译后生成的可执行文件(为了方便,可以把此目录加入到PATH 变量中)
go mod介绍
go modules 是 golang 1.11 新加的特性。现在1.12 已经发布了,是时候用起来了。Modules官方定义为:
模块是相关Go包的集合。modules是源代码交换和版本控制的单元。go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。
GO111MODULE
GO111MODULE 有三个值:off, on和auto(默认值)。
GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。
go mod命令
golang 提供了 go mod命令来管理包。
go help mod
Go mod provides access to operations on modules.Note that support for modules is built into all the go commands,not just 'go mod'. For example, day-to-day adding, removing, upgrading,and downgrading of dependencies should be done using 'go get'.See 'go help modules' for an overview of module functionality.Usage: go mod [arguments]The commands are: download download modules to local cache edit edit go.mod from tools or scripts graph print module requirement graph init initialize new module in current directory tidy add missing and remove unused modules vendor make vendored copy of dependencies verify verify dependencies have expected content why explain why packages or modules are neededUse "go help mod " for more information about a command.
比较常用的是 init,tidy, edit
go mod init: 初始化modules go mod download: 下载依赖的module到本地cache go mod edit: 编辑go.mod文件,选项有-json、-require和-exclude,可以使用帮助go help mod edit go mod graph: 以文本模式打印模块需求图 go mod tidy: 检查,删除错误或者不使用的modules,以及添加缺失的模块 go mod vendor: 生成vendor目录,将依赖复制到vendor目录下面 go mod verify: 验证依赖是否正确 go mod why: 解释为什么需要依赖
使用go mod管理一个新项目
还是以图1所示项目案例为例
1. 初始化项目
进入项目根目录下,以VSCode为例
go mod init chapter2
其中“chapter2”可以根据情况命名,这样就可以在代码里用chapter2访问到其他的模块,如
package mainimport ( "log" "os" _"chapter2/matchers" "chapter2/search")
查看生成的go.mod
module chapter2go 1.14
go.mod 提供了module, require、replace和exclude 四个命令
module 语句指定包的名字(路径)
require 语句指定的依赖项模块
replace 语句可以替换依赖项模块
exclude 语句可以忽略依赖项模块
2. 添加依赖
创建 main.go文件
package mainimport ( "github.com/gin-gonic/gin")func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")}
执行 go run main.go 运行代码会发现 go mod 会自动查找依赖自动下载
再查看 go.mod
module Gonego 1.14require github.com/gin-gonic/gin v1.6.3
go module 安装 package 的原則是先拉最新的 release tag(例如上面的v1.6.3),若无tag则拉最新的commit
go 会自动生成一个 go.sum 文件来记录 dependency tree
使用replace替换无法直接获取的package
由于某些已知的原因,并不是所有的package都能成功下载,比如:golang.org下的包。
modules 可以通过在 go.mod 文件中使用 replace 指令替换成github上对应的库,比如:
replace ( golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a)
goproxy
关于goproxy,简单来说就是一个代理,让我们更方便的下载哪些由于墙的原因而导致无法下载的第三方包,比如golang.org/x/下的包
一般来说,goproxy是和go modules配合使用的。
首先要确保go modules是开启的,环境变量GO11MODULE要打开
GO111MODULE=on