8.4 Go modules 包依赖管理

Go 1.11 新增了对模块的支持,希望借此解决“包依赖管理”。可以通过设置环境变量 GO111MODULE来开启或关闭模块支持,它有三个可选值: off、 on、 auto,默认值是 auto。
  • GO111MODULE=off 无模块支持,go 会从 GOPATH 和 vendor 文件夹寻找包。
  • GO111MODULE=on 模块支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod下载依赖。
  • GO111MODULE=auto 在 GOPATH/src外面且根目录有 go.mod文件时,开启模块支持。

在使用模块的时候, GOPATH是无意义的,不过它还是会把下载的依赖储存在 GOPATH/pkg/mod 中。

运行命令,go help mod ,我们可以看到mod的操作子命令,主要是init、 edit、 tidy。

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 <command> [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 needed
Use "go help mod <command>" for more information about a command.

命令含义: download 下载依赖的module到本地cache edit 编辑go.mod文件 graph 打印模块依赖图 init 在当前文件夹下初始化一个新的module, 创建go.mod文件 tidy 增加丢失的module,去掉未用的module vendor 将依赖复制到vendor下 verify 校验依赖 why 解释为什么需要依赖

为了使用modules来管理项目,我们可以以下几个步骤来操作:

  1. 首先需要设置GO111MODULE ,这里我们设置为auto。
  2. 考虑和原来GOPATH有所隔离,新建立了一个目录D:\gomodules来存放modules管理的项目。
  3. 在D:\gomodules下建立ind项目,建立对应的目录,D:\gomodules\ind
  4. 在ind目录中,我们编写了该项目的主要文件main.go
package main
import (
	"fmt"
	"github.com/gocolly/colly"
)
func main() {
	c := colly.NewCollector()
	// Find and visit all links
	c.OnHTML("a[href]", func(e *colly.HTMLElement) {
		e.Request.Visit(e.Attr("href"))
	})
	c.OnRequest(func(r *colly.Request) {
		fmt.Println("Visiting", r.URL)
	})
	c.Visit("http://go-colly.org/")
}
  1. 第一次需要我们运行init命令初始化:
    1. D:\gomodules\ind>go mod init ind
    2. go: creating new go.mod: module ind
    3. 可以在ind目录看到新生成了一个文件:go.mod ,这个modules名字叫ind。
  2. 接下来我们运行go mod tidy 命令,发现如下图一样出现报错,这主要是众所周知的网络原因,由于这里主要是golang.org/x下的包,所以可以简单使用replace命令来解决这个问题,如果是其他厂商的依赖包,还是优先解决网络问题。
    1. 然后重复运行go mod tidy ,如果出错在使用replace,直到能正常运行go mod tidy 命令完成。
    2. go mod edit -replace=old[@v]=new[@v]
    3. 注意:replace版本号可以在错误信息中看到。
    4. D:\gomodules\ind>go mod edit -replace=golang.org/x/net@v0.0.0-20181114220301-adae6a3d119a=github.com/golang/net@v0.0.0-20181114220301-adae6a3d119a
  3. 我们看到在ind目录下面多了2个文件,分别是go.mod和go.sum。
module ind
replace (
	golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01 => github.com/golang/net v0.0.0-20180218175443-cbe0f9307d01
	golang.org/x/net v0.0.0-20181114220301-adae6a3d119a => github.com/golang/net v0.0.0-20181114220301-adae6a3d119a
)
require (
	github.com/PuerkitoBio/goquery v1.5.0 // indirect
	github.com/antchfx/htmlquery v0.0.0-20181207070731-9784ecda34b7 // indirect
	github.com/antchfx/xmlquery v0.0.0-20181204011708-431a9e9e7c44 // indirect
	github.com/antchfx/xpath v0.0.0-20181208024549-4bbdf6db12aa // indirect
	github.com/gobwas/glob v0.2.3 // indirect
	github.com/gocolly/colly v1.1.0
	github.com/kennygrant/sanitize v1.2.4 // indirect
	github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
	github.com/temoto/robotstxt v0.0.0-20180810133444-97ee4a9ee6ea // indirect
)

go.mod文件可以通过require,replace和exclude语句使用的精确软件包集。

  • require语句指定的依赖项模块
  • replace语句可以替换依赖项模块
  • exclude语句可以忽略依赖项模块

go.sum文件

github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/antchfx/htmlquery v0.0.0-20181207070731-9784ecda34b7 h1:w7OFcAjjWOJ/Fp9/dlvikG46C44FV/B8G42Tj+KlFUk=
github.com/antchfx/htmlquery v0.0.0-20181207070731-9784ecda34b7/go.mod h1:MS9yksVSQXls00iXkiMqXr0J+umL/AmxXKuP28SUJM8=
github.com/antchfx/xmlquery v0.0.0-20181204011708-431a9e9e7c44 h1:utJNS82e0x9ZhwWvitDlUv2+0HgGYfyrSKX9hDf0uW0=
github.com/antchfx/xmlquery v0.0.0-20181204011708-431a9e9e7c44/go.mod h1:/+CnyD/DzHRnv2eRxrVbieRU/FIF6N0C+7oTtyUtCKk=
github.com/antchfx/xpath v0.0.0-20181208024549-4bbdf6db12aa h1:lL66YnJWy1tHlhjSx8fXnpgmv8kQVYnI4ilbYpNB6Zs=
github.com/antchfx/xpath v0.0.0-20181208024549-4bbdf6db12aa/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gocolly/colly v1.1.0 h1:B1M8NzjFpuhagut8f2ILUDlWMag+nTx+PWEmPy7RhrE=
github.com/gocolly/colly v1.1.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA=
github.com/golang/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:98y8FxUyMjTdJ5eOj/8vzuiVO14/dkJ98NYhEPG8QGY=
github.com/golang/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:98y8FxUyMjTdJ5eOj/8vzuiVO14/dkJ98NYhEPG8QGY=
github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/temoto/robotstxt v0.0.0-20180810133444-97ee4a9ee6ea h1:hH8P1IiDpzRU6ZDbDh/RDnVuezi2oOXJpApa06M0zyI=
github.com/temoto/robotstxt v0.0.0-20180810133444-97ee4a9ee6ea/go.mod h1:aOux3gHPCftJ3KHq6Pz/AlDjYJ7Y+yKfm1gU/3B0u04=

打开目录GOPATH/pkg/mod,我们可以看到这个项目下的依赖包都下载过来了。

下一节:包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他运算符