我是靠谱客的博主 温暖八宝粥,最近开发中收集的这篇文章主要介绍go mod 常用操作1. 开启Go module2. go get使用3. mod基本操作4. mod高级操作5. 进阶6. 下载路径替换,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 1. 开启Go module
    • 1.11和1.12版本
    • 1.13版本之后
    • goLand开启 go mod
  • 2. go get使用
  • 3. mod基本操作
  • 4. mod高级操作
    • 4.1 retract
  • 5. 进阶
    • 5.1 版本号规范
    • 5.2 伪版本
    • 5.3 indirect标志
      • 5.3.1 直接依赖未启用 Go module
      • 5.3.2 直接依赖go.mod 文件中缺失部分依赖
      • 5.3.3 如果查找间接依赖
    • 5.4 replace使用
    • 5.5 exclude使用
    • 5.6 包缓存
    • 5.7 下载过程查看
  • 6. 下载路径替换

环境

  • Windows10
  • GO:1.13

1. 开启Go module

1.11和1.12版本

将下面两个设置添加到系统的环境变量中

GO111MODULE=on
GOPROXY=https://goproxy.io

1.13版本之后

需要注意的是这种方式并不会覆盖之前的配置,有点坑,你需要先把之前的给删掉再设置

# 1.13之后,这个都是默认开启的
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

如果遇到校验go.sum出现问题的,把GOSUMDB关掉就好了

go env -w GOSUMDB=off

或者将域名设置为私有

go env -w GOPRIVATE=pibigstar.com

goLand开启 go mod

2. go get使用

使用go module之后,go get 拉取依赖的方式就发生了变化

  • 下载项目依赖
go get ./...
  • 拉取最新的版本(优先择取 tag)
go get golang.org/x/text@latest
  • 拉取 master 分支的最新 commit
go get golang.org/x/text@master
  • 拉取 tag 为 v0.3.2 的 commit
go get golang.org/x/text@v0.3.2
  • 拉取 hash 为 342b231 的 commit,最终会被转换为 v0.3.2:
go get golang.org/x/text@342b2e
  • 指定版本拉取,拉取v3版本
go get github.com/smartwalle/alipay/v3
  • 更新
go get -u

查看可执行文件的mod信息

go version -m gen

3. mod基本操作

  1. 初始化一个moudle,模块名为你项目名
go mod init 模块名
  1. 下载modules到本地cache

目前所有模块版本数据均缓存在 $GOPATH/pkg/mod和 ​$GOPATH/pkg/sum

go mod download
  1. 编辑go.mod文件
    选项有-json-require-exclude,可以使用帮助go help mod edit
go mod edit
  1. 以文本模式打印模块需求图
go mod graph
  1. 删除错误或者不使用的modules
go mod tidy
  1. 生成vendor目录
go mod vendor
  1. 验证依赖是否正确
go mod verify
  1. 查看依赖关系
go mod why -m githuh.com/pibigstar/go-demo

4. mod高级操作

  1. 更新到最新版本
go get github.com/gogf/gf@version

如果没有指明 version 的情况下,则默认先下载打了 tag 的 release 版本,比如 v0.4.5 或者 v1.2.3;如果没有 release 版本,则下载最新的 pre release 版本,比如 v0.0.1-pre1。如果还没有则下载最新的 commit

  1. 更新到某个分支最新的代码
go get github.com/gogf/gf@master
  1. 更新到最新的修订版(只改bug的版本)
go get -u=patch github.com/gogf/gf
  1. 替代只能翻墙下载的库
go mod edit -replace=golang.org/x/crypto@v0.0.0=github.com/golang/crypto@latest
go mod edit -replace=golang.org/x/sys@v0.0.0=github.com/golang/sys@latest
  1. 清理moudle 缓存
go clean -modcache
  1. 查看可下载版本
 go list -m -versions github.com/gogf/gf
  1. 查看撤回的版本(1.16后才支持)
go list -m -versions -retracted github.com/polaris1119/foo
  1. 查看当前项目中是否依赖了撤回的版本
go list -m -u all

4.1 retract

它可以帮助我们撤回某个版本,比如你推送了 v0.2.0 版本,这时别人都依赖了你的 v0.2.0 版本,但你突然发现这个版本有bug,但你不能删除这个版本了,这时你可以发布一个 v0.2.1版本,该版本的go.mod里面增加 retract v0.2.0 将 v0.2.0 版本给撤回,这时别人如果依赖了v0.2.0版本就会给别人提醒,类似于 函数注释 Deprecate 功能

module github.com/pibigstar/go-demo
go 1.16

retract (
    // 这个版本有bug
    v0.2.0
    // 也可撤回多个版本
    [v1.0.0, v1.0.1]
)

5. 进阶

5.1 版本号规范

go mod 对版本号的定义是有一定要求的,它要求的格式为 v<major>.<minor>.<patch>,如果major版本号大于1时,其版本号还需要体现在Module名字中。比如 我的项目github.com/pibigstar/go-demo,如果我的版本号增长到v2.x.x时,我的Module名字也需要相应的改变为: github.com/pibigstar/go-demo/v2, 有人可能就要问了,我不改可以吗? 可以的!但是go mod 会在你依赖的后面打一个+incompatible 标志

5.2 伪版本

我们将项目上传到github后,如果不打tag,或tag不符合v<major>.<minor>.<patch>这个格式,那么当我们用go mod 去拉这个项目的时候,就会将 commitId 作为版本号,它的格式大概是 vx.y.z-yyyymmddhhmmss-abcdef格式

虽然不太好看,但是这个玩意其实挺有用的,省的你每次都需要打tag了,这里介绍一个如果直接拉取最后一次提交的版本

require (
	github.com/pibigstar/go-demo master
)

我们直接在后面写 master 分支,这样它就会拉取master分支最后一次提交的commitId 作为版本号

5.3 indirect标志

我们用 go mod 的时候应该经常会看到 有的依赖后面会打了一个 // indirect 的标识位,这个标识位是表示 间接的依赖。

什么叫间接依赖呢?打个比方,项目A依赖了项目B,项目B又依赖了项目C,那么对项目A而言,项目C就是间接依赖,这里要注意,并不是所有的间接依赖都会出现在 go.mod文件中。间接依赖出现在go.mod文件的情况,可能符合下面的场景的一种或多种:

  • 直接依赖未启用 Go module
  • 直接依赖go.mod 文件中缺失部分依赖

5.3.1 直接依赖未启用 Go module

如下图所示,Module A 依赖 B,但是 B 还未切换成 Module,即没有go.mod文件,此时,当使用go mod tidy命令更新A的go.mod文件时,B的两个依赖B1和B2将会被添加到A的go.mod文件中(前提是A之前没有依赖B1和B2),并且B1 和B2还会被添加// indirect的注释。


那么项目A的依赖关系就会变成下面这个样子

require (
    B vx.x.x
    B1 vx.x.x // indirect
    B2 vx.x.x // indirect
)

5.3.2 直接依赖go.mod 文件中缺失部分依赖

如下图所示,Module B虽然提供了go.mod文件中,但go.mod文件中只添加了依赖B1,那么此时A在引用B时,则会在A的go.mod文件中添加B2作为间接依赖,B1则不会出现在A的go.mod文件中。


此时项目A的依赖关系就会变成下面这个样子

require (
    B vx.x.x
    B2 vx.x.x // indirect
)

间接依赖出现在go.mod中,可以一定程度上说明依赖有瑕疵,要么是其不支持Go module,要么是其go.mod文件不完整。
由于Go 语言从v1.11版本才推出module的特性,众多开源软件迁移到go module还需要一段时间,在过渡期必然会出现间接依赖,但随着时间的推进,在go.mod中出现// indirect的机率会越来越低。
出现间接依赖可能意味着你在使用过时的软件,如果有精力的话还是推荐尽快消除间接依赖。可以通过使用依赖的新版本或者替换依赖的方式消除间接依赖。

5.3.3 如果查找间接依赖

可以通过 go mod why -m <pkg> 来查看这个间接依赖是被谁引入的

5.4 replace使用

replace指替换,它指示编译工具替换require指定中出现的包

这里要注意两点:

  • replace只在 main module里面有效

什么叫main module? 打个比方,项目A 的module用replace替换了本地文件,那么当项目B引用项目A后,项目A的replace会失效,此时对replace而言,项目A就是 main module

  • replace指定中需要替换的包及其版本号必须出现在require列表中才有效

这里我再简单谈下replace的使用场景

  • 替换无法下载的包
  • 替换本地自己的包
  • 替换fork包

有时候我们依赖的第三方库可能有bug,我们就可以fork一份他们的库,然后自己改下,然后通过replace将我们fork的替换成原来的

5.5 exclude使用

go.mod文件中的exclude指令用于排除某个包的特定版本,其与replace类似,也仅在当前module为main module时有效,其他项目引用当前项目时,exclude指令会被忽略。
exclude指令在实际的项目中很少被使用,因为很少会显式地排除某个包的某个版本,除非我们知道某个版本有严重bug。 比如指令exclude github.com/pibigstar/go-demo v1.1.0,表示不使用v1.1.0 版本。

5.6 包缓存

最后简单谈一下当我们使用 go mod 后包缓存存储问题,依赖包存储在$GOPATH/pkg/mod,该目录中可以存储特定依赖包的多个版本。需要注意的是$GOPATH/pkg/mod目录下有个cache目录,它用来存储依赖包的缓存,简单说,go命令每次下载新的依赖包都会在该cache目录中保存一份,每个版本都会有一份缓存。

值得注意的是包名大小写问题,有时我们使用的包名中会包含大写字母,GOMODULE模式下,在存储时会将包名做大小写编码处理,即每个大写字母将变!+相应的小写字母,比如github.com/pibigstar/GO-demo 包在存储时将会被放置在$GOPATH/pkg/mod/github.com/pibigstar/!g!o-demo目录中。所以这里我不推荐你用大写字母定义包名

5.7 下载过程查看

我们可以在包下载路径后面新增 ?go-get=1 参数,然后浏览器访问 https://gitee.com/pibigstar/go-demo?go-get=1,然后查看源码就能看到该包拉取的具体路径是什么

6. 下载路径替换

当我们的module不是放在域名的443或80端口时,这时就会比较麻烦,因为go mod 不支持 pibigstar.com:8000/group/util 这种结构,这种是无法下载的,不过我们可以使用 git 的替换功能,实现这个下载

git config --global url."http://pibigstar.com:8000/".insteadof "https://pibigstar.com/"

这样我们使用go mod 就可以用下面的路径

require (
	pibigstar.com/group/util v1.0.0
)

这个pibigstar.com 是可以随意写的,只要是一个可访问的域名

最后

以上就是温暖八宝粥为你收集整理的go mod 常用操作1. 开启Go module2. go get使用3. mod基本操作4. mod高级操作5. 进阶6. 下载路径替换的全部内容,希望文章能够帮你解决go mod 常用操作1. 开启Go module2. go get使用3. mod基本操作4. mod高级操作5. 进阶6. 下载路径替换所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部