文章目录
一、关于Go modules1. GOPATH2. 为什么弃用 GOPATH 模式3. Go Modules基本使用(Go mod 使用记录)4. Go modules 中常用环境变量GO111MODULE 定义GO111MODULE 变量在不同 Go 版本有不同的语义Go 1.11 和 1.12 阶段Go 1.13 阶段为什么命名为GO111MODULEGOPROXY设置二、工作常见问题总结go get 报错 go: cannot use path@version syntax in GOPATH mode 解决方法三、Goland使用Go mod模式创建工程一、关于Go modules
Go Modules 终极入门
参考URL: /EDDYCJY/article/details/104528976
Go modules 是 Go 语言中正式官宣的项目依赖解决方案,Go modules(前身为vgo)于 Go1.11 正式发布,在 Go1.14 已经准备好,并且可以用在生产上(ready for production)了,Go 官方也鼓励所有用户从其他依赖项管理工具迁移到 Go modules。
Go modules 是 Go 语言的依赖解决方案,发布于 Go1.11,成长于 Go1.12,丰富于 Go1.13,正式于 Go1.14 推荐在生产上使用。
因为为了更愉快的使用go,我个人建议还是不要考虑太老版本的go了。至少 Go1.13起步! 🤩
Go moudles 目前集成在 Go 的工具链中,只要安装了 Go,自然而然也就可以使用 Go moudles 了,而 Go modules 的出现也解决了在 Go1.11 前的几个常见争议问题:
Go 语言长久以来的依赖管理问题。
“淘汰”现有的 GOPATH 的使用模式。
统一社区中的其它的依赖管理工具(提供迁移功能)。
1. GOPATH
我们输入go env命令行后可以查看到 GOPATH 变量的结果,我们进入到该目录下进行查看,如下:
go├── bin├── pkg└── src├── ├── ├── ├── gopkg.in....
GOPATH目录下一共包含了三个子目录,分别是:
bin:存储所编译生成的二进制文件。pkg:存储预编译的目标文件,以加快程序的后续编译速度。src:存储所有.go文件或源代码。在编写 Go 应用程序,程序包和库时,一般会以$GOPATH/src//foo/bar的路径进行存放。
因此在使用 GOPATH 模式下,我们需要将应用代码存放在固定的$GOPATH/src
目录下,并且如果执行go get来拉取外部依赖会自动下载并安装到$GOPATH目录下。
2. 为什么弃用 GOPATH 模式
在 GOPATH 的 $GOPATH/src 下进行 .go 文件或源代码的存储,我们可以称其为 GOPATH 的模式,这个模式,看起来好像没有什么问题,那么为什么我们要弃用呢,参见如下原因:
GOPATH 模式下没有版本控制的概念,具有致命的缺陷,至少会造成以下问题:
在执行go get的时候,你无法传达任何的版本信息的期望,也就是说你也无法知道自己当前更新的是哪一个版本,也无法通过指定来拉取自己所期望的具体版本。
在运行 Go 应用程序的时候,你无法保证其它人与你所期望依赖的第三方库是相同的版本,也就是说在项目依赖库的管理上,你无法保证所有人的依赖版本都一致。
你没办法处理 v1、v2、v3 等等不同版本的引用问题,因为 GOPATH 模式下的导入路径都是一样的,都是/foo/bar。
Go 语言官方从 Go1.11 起开始推进 Go modules(前身vgo),Go1.13 起不再推荐使用 GOPATH 的使用模式,Go modules 也渐趋稳定,因此新项目也没有必要继续使用GOPATH模式。
3. Go Modules基本使用(Go mod 使用记录)
在 Go modules 中,我们能够使用如下命令进行操作:
go.mod 可以让你摆脱GOPATH对项目的约束,同时也是解决GoLand问题的核心。
初始化项目
使用 go mod init 初始化一个 go.mod 文件
go mod init
找到项目依赖(整理依赖包)
使用 go mod tidy 找到项目依赖,并写入到 go.mod
go mod tidy
如果想缓存到vendor目录
go mod vendor
更新已有包版本
如果我们想要更新一个已在 go.mod 文件列出的包,可以使用 go get -u PKG_PATH
如,要更新 /gookit/filter 到最新版本:
go get -u /gookit/filter
4. Go modules 中常用环境变量
在 Go modules 中有如下常用环境变量,我们可以通过 go env 命令来进行查看,如下:
GO111MODULE 定义
GO111MODULE 是个啥?
/p/374372749
Go语言提供了 GO111MODULE 这个环境变量来作为 Go modules 的开关,其允许设置以下参数:
auto:Go 命令行工具在同时满足以下两个条件时使用 Go Modules:
当前目录不在 GOPATH/src/ 下;
在当前目录或上层目录中存在 go.mod 文件。
GOPATH 模式(GO111MODULE=off):Go 命令行工具从不使用 Go Modules。相反,它查找 vendor 目录和 GOPATH 以查找依赖项。
GO111MODULE=on 模块支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod 下载依赖。
Go Modules 模式(GO111MODULE=on):Go 命令行工具只使用 Go Modules,从不咨询 GOPATH。GOPATH 不再作为导入目录,但它仍然存储下载的依赖项(GOPATH/pkg/mod/)和已安装的命令(GOPATH/bin/),只是移除了 GOPATH/src/。
总结:在使用Go Modules 的时候,GOPATH 是无意义的,不过它还是会把下载的依赖储存在 $GOPATH/src/mod 中,也会把 go install 的结果放在 $GOPATH/bin 中。
总结:意思 就是 新版本建议使用Go Modules 模式, src 源码路径可以放置到任何地方,不受限于GOPATH目录。
GO111MODULE 变量在不同 Go 版本有不同的语义
什么时候用 GOPATH, 什么时候用 GOMODULE ? 这是个问题,需要通过 GO111MODULE 来解决。
在go1.11版本前,想要对go语言包进行管理,只能依赖第三方库实现,比如Vendor,GoVendor,GoDep,Dep,Glide等等。
Go 1.11 和 1.12 阶段
即使项目在您的 GOPATH 中,GO111MODULE = on 仍将强制使用 Go 模块。仍然需要 go.mod 才能正常工作。
GO111MODULE = off
强制 Go 表现出 GOPATH 方式,即使你的项目不在 GOPATH 目录里。
GO111MODULE = auto 是默认模式。
在这种模式下,Go 会表现: 当项目路径在 GOPATH 目录外部时, 设置为 GO111MODULE = on 当项目路径位于 GOPATH 内部时,即使存在 go.mod, 设置为 GO111MODULE = off。
Go 1.13 阶段
在 Go 1.13 下, GO111MODULE 的默认行为 (auto) 语义变了。
当存在 go.mod 文件时或处于 GOPATH 外, 其行为均会等同于 GO111MODULE=on。相当于 Go 1.13 下你可以将所有的代码仓库均不存储在 GOPATH 下。
当项目目录处于 GOPATH 内,且没有 go.mod 文件存在时其行为会等同于 GO111MODULE=off。
为什么命名为GO111MODULE
你可能会留意到 GO111MODULE 这个名字比较“奇特”,实际上在 Go 语言中经常会有这类阶段性的变量, GO111MODULE 这个命名代表着Go语言在 1.11 版本添加的,针对 Module 的变量。
像是在 Go1.5 版本的时候,也发布了一个系统环境变量 GO15VENDOREXPERIMENT,作用是用于开启 vendor 目录的支持,当时其默认值也不是开启,仅仅作为 experimental。其随后在 Go1.6 版本时也将默认值改为了开启,并且最后作为了official,GO15VENDOREXPERIMENT 系统变量就退出了历史舞台。
而未来 GO111MODULE 这一个系统环境变量也会面临这个问题,也会先调整为默认值为 on(曾经在Go1.13想想改为 on,并且已经合并了 PR,但最后因为种种原因改回了 auto),然后再把 GO111MODULE 的支持给去掉,我们猜测应该会在 Go2 将 GO111MODULE 给去掉,因为如果直接去掉 GO111MODULE 的支持,会存在兼容性问题。
GOPROXY设置
这个环境变量主要是用于设置 Go 模块代理(Go module proxy),其作用是用于使 Go 在后续拉取模块版本时能够脱离传统的 VCS 方式,直接通过镜像站点来快速拉取。
GOPROXY 的默认值是:,direct,这有一个很严重的问题,就是 在国内是无法访问的,因此这会直接卡住你的第一步,所以你必须在开启 Go modules 的时,同时设置国内的 Go 模块代理,执行如下命令:
go env -w GOPROXY=,direct
GOPROXY 的值是一个以英文逗号 “,” 分割的 Go 模块代理列表,允许设置多个模块代理,假设你不想使用,也可以将其设置为 “off” ,这将会禁止 Go 在后续操作中使用任何 Go 模块代理。
二、工作常见问题总结
go get 报错 go: cannot use path@version syntax in GOPATH mode 解决方法
参考:/kubernetes/client-go/blob/master/INSTALL.md#enabling-go-modules
需要开启 GO111MODULE,默认是 auto,
添加 export GO111MODULE=on 即可。修改完记得source
export GO111MODULE=on
GO的语言版本大于1.13的时候,执行以下命令即可
go env -w GO111MODULE=on
三、Goland使用Go mod模式创建工程
go mod 可以让你摆脱GOPATH对项目的约束,同时也是解决GoLand问题的核心。
1、创建新工程
操作步骤: 菜单栏File > New > Project 通过Go modules模式进行程序创建
GOPROXY=,direct
2、修改当前工程
如果已经有当前工程,那么对该工程进行修改为go mod模式有两种办法:
在Terminal控制台输入go mod init 命令进行创建