Python有pip,Nodejs有npm。是否是别的语言有包管理工具,因此go就要有?固然不是,来看看下面这段代码:git
import ( "github.com/TomatoMr/something" )
这是go引用包的方式,很明显这是个第三方包,那么它在咱们本机上具体是怎么被找到的呢?
先说说尚未go mod的时候,它是这么找的:github
找到包以后就会将它下载到GOPATH下,简单易懂。但这不足够,好比当我对这些包有了版本控制的需求,那这个包管理方式还有所欠缺,具体场景以下:golang
我引用的第三包有不一样的版本,若是我不用其余的包管理工具,那么我默认得到的包是最新版,也就是v0.0.2的版本,而这时的版本的Hi()方法已经不存在了,而个人代码里面仍然调用了Hi()方法,这就会使个人代码报错,我如今须要有版本控制的包管理工具。shell
在go的1.11版本以后,go mod就被指定为亲生的包管理工具,它提供了更加灵活的管理办法,能够对包进行版本控制,并且你的项目也不须要必定放在GOPATH下了(放GOPATH下也没啥很差)。看看它是具体怎么作的:npm
$ go mod init <module_name> # 对一个项目的module进行初始化,module_name是选填的,能够在初始化的时候就制定module名 $ go mod tidy # 添加包,清除没有引用的包
执行完两句命令以后,你会看到,项目下多了go.mod和go.sum文件。缓存
go.mod: 能够理解为包管理文件
go.sum: 能够理解为包的版本控制文件服务器
好了,咱们如今来看看,咱们前面的需求,我想要引入包的时候可以选择版本,用gomod怎么作。咱们先将go.mod文件中的版本号改成:v0.0.1。ide
再在项目根目录执行工具
$ go mod tidy
咱们能够看到go.sum文件也相应地改变了。学习
再看看咱们的代码,调用Hi()方法没有报错了。
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 # 复制依赖包到vendor 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.
使用go mod以后,包下载以后是放在了$GOPATH/pkg/mod下:
GO111MODULE= # 默认当项目中有go.mod文件就用go mod管理,没有就仍是旧的方式,GO111MODULE=on强制使用go mod,GO111MODULE=off关闭go mod GOPROXY="https://goproxy.cn,https://proxy.golang.org,https://goproxy.io,direct" # GOPROXY设置代理,我建议设置成与我上面一致,第一个地址是七牛云的代理,防止被墙,direct值得是从源站下载 GOSUMDB="sum.golang.org" # 指示校验和服务器的地址和公钥,这里指"sum.golang.org"的公钥可省略,若要关闭校验,GOSUMDB=off。 GOPRIVATE="" # GOPRIVATE表示私有仓库。私有仓库下的全部依赖一概从源站下载,并且不作校验。 GONOPROXY="" # 与GOPROXY对应 GONOSUMDB="" # 与GOSUMDB对应
熟悉这几个环境变量有实际的好处,好比由于某种不可描述的缘由而不能下载国外网站的包,又或者由于本身公司搭建了私有仓库,须要作相应的配置。
有这样一写应用场景,好比说:
这个时候就须要replace来替换包,以下:
package main import ( "github.com/TomatoMr/bar" # 在这个地址下面没有这个包,多是原包换名字或者这是我一个本地包 "github.com/TomatoMr/something" ) func main() { something.Hello() something.Hi() bar.HelloBar() }
看看咱们在go.mod文件里面应该怎么修改:
module Foo go 1.13 require ( github.com/TomatoMr/something v0.0.1 ) replace github.com/TomatoMr/bar => D:\\share\\go\\src\\foo\\bar # 将bar这个包替换成个人本地路径(绝对路径或者相对路径都可)
而后执行:
go mod tidy
接着go.mod发生了变化:
module Foo go 1.13 require ( github.com/TomatoMr/bar v0.0.0-00010101000000-000000000000 github.com/TomatoMr/something v0.0.1 ) replace github.com/TomatoMr/bar => D:\\share\\go\\src\\foo\\bar
能够看到github.com/TomatoMr/bar已经require进去了。
go clean -modcache
这个比较少用,当你的环境被破坏,或者想删除全部的mod缓存的话,能够这么干。
欢迎关注个人公众号:onepunchgo,会整理相关的文档和资料。