简单聊聊go语言中引用模块的版本控制以及invalid: should be v0 or v1, not v2问题的解决

文章目录

  • 前言
  • 具体示例
  • 手动升级依赖库
  • should be v0 or v1, not v2
  • 总结

前言

如果你接触go语言比较早,一定有过当年所有go源码全部放入 GOPATH 下的混乱经历,不过发展到今天,go的包管理使用 go.modgo.work 已经能得心应手,满足绝大多数的开发不成问题,其实在 go.mod 引入之后,go的包管理就有了明显的改善,再也不像原来那样好似闹着玩一样了,关于go.mod使用和管理我也是一知半解,想要教程可去官网或者查找各种详解资料,只是最近有点疑惑,这个go.mod以及go.sum要不要自己手动管理,带着这个疑问我做了一些测试可以得出,go.mod 的最初不需要手动管理,如果后来需要调整引入包的版本,可以手动调整。

以下是来自ChatGPT的关于 go.modgo.sum 作用的回答,还是比较清晰的,如果还不太明白可以看看后面的例子感受一下

go.modgo.sum 文件是 Go Modules 的重要组成部分,用于管理项目的依赖关系。共同为 Go 项目提供了依赖管理的基础,确保了项目的稳定性和可维护性:

  1. go.mod
  • 定义了项目的模块信息,包括模块名称、版本和依赖项等。
  • 确定了项目的模块根目录。
  • 记录了项目所依赖的其他模块及其版本信息。
  • 提供了一种清晰的方式来管理项目的依赖关系,使得项目的构建和维护更加可靠和可控。
  1. go.sum
  • 记录了每个依赖模块的哈希值,以保证项目的构建是可复现的。
  • 确保了项目依赖项的完整性,防止恶意篡改或不完整的依赖项被用于构建项目。
  • 当使用 go mod verify 命令时,go.sum 文件会被用来验证依赖项的完整性。

通常情况下,go.mod 文件是由 go 工具自动生成和管理的,不需要手动修改。当你执行一些与模块相关的操作时(例如使用 go get 安装新的依赖、使用 go mod tidy 整理依赖、或者更新依赖版本等),go 工具会自动更新 go.mod 文件以反映这些变化,但是,在某些特定情况下,你可能需要手动编辑 go.mod 文件,例如:

  1. 手动添加或删除依赖项:你可能希望手动添加新的依赖项,或者删除不再需要的依赖项。在这种情况下,你需要手动编辑 go.mod 文件,并执行 go mod tidy 命令以确保依赖关系的一致性。

  2. 手动指定依赖版本:有时你可能希望显式地指定某个依赖项的特定版本。在这种情况下,你需要编辑 go.mod 文件,并指定对应的版本号。

总的来说,虽然 go.mod 文件通常是由 go 工具自动维护的,但在某些情况下手动编辑是必要的。在编辑 go.mod 文件时,确保遵循 Go 模块的规范,并注意保持文件的格式正确和依赖关系的一致性。

具体示例

假设有一个需求,要读取 .xlsx 格式表格文件的所有页签名,解析Excel文件这么基础的工作肯定有人写好了,我们直接引入module不需要重新再写一遍了,我们新建一个包含go.mod的工程来使用它

$ mkdir lib_xlsx
$ cd lib_xlsx
$ go mod init lib_xlsx
go: creating new go.mod: module lib_xlsx

$ touch lib_xlsx.go
$ ls
go.mod  lib_xlsx.go

go.mod的初始文件内容为

module lib_xlsx

go 1.19

打开 lib_xlsx.go 文件编写如下代码:

package main

import (
   "fmt"
   "log"

   "github.com/tealeg/xlsx"
)

func main() {

   xlFile, err := xlsx.OpenFile("example.xlsx")
   if err != nil {
      log.Fatalf("Error opening file: %s", err)
   }

   for _, sheet := range xlFile.Sheets {
      fmt.Println("Sheet Name:", sheet.Name)
   }
}

代码是不是很简单,此时不出意外IDE会提醒你 could not import github.com/tealeg/xlsx 的错误,因为我们还没下载这个包,只需要在命令行执行 go get github.com/tealeg/xlsx 既可下载,同时会自动更新 go.modgo.sum 文件

$ go get github.com/tealeg/xlsx
go: added github.com/tealeg/xlsx v1.0.5

自动更新后的 go.mod 文件内容,引用了 github.com/tealeg/xlsx 库的 v1.0.5 版本

module lib_xlsx

go 1.19

require github.com/tealeg/xlsx v1.0.5

自动更新后的 go.sum 文件内容,记录了各个依赖库、间接依赖库以及项目go.mod文件的hash值

github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

此时程序已经写完,依赖关系也已经下载好了,直接运行就可以

$ go run .
Sheet Name: Sheet1
Sheet Name: Sheet2
Sheet Name: Sheet3

因为 go.modgo.sum 文件共同为这个项目提供了依赖管理,别人在下载你这份源码时,先执行 go mod tidy 根据依赖关系下载正确的版本库,之后就可以直接编译运行了

手动升级依赖库

到目前为止,我们并没有手动编辑过 go.mod 文件,只是在使用 go get github.com/tealeg/xlsx 自动更新了这个文件,假设这个例子的需求要扩展,引用的 github.com/tealeg/xlsx 功能是在v1.0.6 版本新加的,那么我么只需要将 go.mod 文件中的 v1.0.5 替换成 v1.0.6,然后执行 go mod tidy 即可下载正确的依赖库。

但如果要引用的依赖库版本不是 v0 或者 v1 版本的就不能这么处理了,具体做法看下面的问题。

should be v0 or v1, not v2

当你手动把 go.mod 文件中的 v1.0.5 替换成 v2.x.x 执行 go mod tidy 时就会报一个错误

errors parsing go.mod: /xxx/lib_xlsx/go.mod:5: require github.com/tealeg/xlsx: version “v2.0.0” invalid: should be v0 or v1, not v2

问题的原因及细节可以参考这篇文档《[Go] 到底 go get 的版號怎麼運作的?》中关于“Semantic import version”的描述

复杂的原因简单说:Go有一个规范,就是在启用了Go Module的仓库上如果想使用 v2 及以上版本,需要在原引用库上添加版本标识简写,比如这个例子中,我们需要将 lib_xlsx.go 文件中引用包的代码改成下面这样

import (
   "fmt"
   "log"

   "github.com/tealeg/xlsx/v3"
)

执行 go mod tidy 命令

$ go mod tidy
go: finding module for package github.com/tealeg/xlsx/v3
go: found github.com/tealeg/xlsx/v3 in github.com/tealeg/xlsx/v3 v3.3.5

如果遇到下面这个问题,确认修改无误的话多尝试几次

$ go mod tidy
go: finding module for package github.com/tealeg/xlsx/v3
lib_xlsx imports
github.com/tealeg/xlsx/v3: module github.com/tealeg/xlsx/v3: Get “https://proxy.golang.org/github.com/tealeg/xlsx/v3/@v/list”: EOF

执行过后 go.mod 和 go.sum 两个文件改变后的内容如下:

module lib_xlsx

go 1.19

require github.com/tealeg/xlsx/v3 v3.3.5

require (
   github.com/frankban/quicktest v1.14.6 // indirect
   github.com/google/btree v1.0.0 // indirect
   github.com/google/go-cmp v0.5.9 // indirect
   github.com/kr/pretty v0.3.1 // indirect
   github.com/kr/text v0.2.0 // indirect
   github.com/peterbourgon/diskv/v3 v3.0.1 // indirect
   github.com/rogpeppe/fastuuid v1.2.0 // indirect
   github.com/rogpeppe/go-internal v1.9.0 // indirect
   github.com/shabbyrobe/xmlwriter v0.0.0-20200208144257-9fca06d00ffa // indirect
   golang.org/x/text v0.3.8 // indirect
)
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/peterbourgon/diskv/v3 v3.0.1 h1:x06SQA46+PKIUftmEujdwSEpIx8kR+M9eLYsUxeYveU=
github.com/peterbourgon/diskv/v3 v3.0.1/go.mod h1:kJ5Ny7vLdARGU3WUuy6uzO6T0nb/2gWcT1JiBvRmb5o=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug=
github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/shabbyrobe/xmlwriter v0.0.0-20200208144257-9fca06d00ffa h1:2cO3RojjYl3hVTbEvJVqrMaFmORhL6O06qdW42toftk=
github.com/shabbyrobe/xmlwriter v0.0.0-20200208144257-9fca06d00ffa/go.mod h1:Yjr3bdWaVWyME1kha7X0jsz3k2DgXNa1Pj3XGyUAbx8=
github.com/tealeg/xlsx/v3 v3.3.5 h1:dzmns01jRf0SveBe7VqkcO2LCLOcypcDI6H66PiZycQ=
github.com/tealeg/xlsx/v3 v3.3.5/go.mod h1:KV4FTFtvGy0TBlOivJLZu/YNZk6e0Qtk7eOSglWksuA=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=

将 github.com/tealeg/xlsx 从 v1.0.5 升级到 v3.3.5 真是加了不少间接依赖库啊

至此 go.mod 文件的自动更新和手动维护我们就都尝试过了

总结

  • go.modgo.sum 文件是 Go Modules 的重要组成部分,用于管理项目的依赖关系
  • go.mod 文件是由 go 工具自动生成和管理的,不需要手动修改,常用命令 go get xxxgo mod tidy
  • 如果想显式地指定某个依赖项的特定版本才需要手动编辑 go.mod 文件
  • go.sum 文件记录了每个依赖模块的哈希值,以保证项目的构建是可复现的
  • 如果在启用了Go Module的仓库想使用 v2 及以上版本,需要在原引用库路径末尾添加版本标识简写,比如v2、v3等

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

穷则独善其身,达则兼济天下,如今在这纷繁的世间,独善其身已实属不易,天下交给你们,我自顺其自然吧~

你可能感兴趣的:(Go,golang,开发语言,go.mod,.xlsx,依赖库版本)