Go mod 同一个module的多版本问题
source link: https://luckymrwang.github.io/2022/05/24/Go-mod-%E5%90%8C%E4%B8%80%E4%B8%AAmodule%E7%9A%84%E5%A4%9A%E7%89%88%E6%9C%AC%E9%97%AE%E9%A2%98/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
首先,注意区分使用Go mod后,module和package的概念
- module是go mod的引入单位,go.mod文件里引入的是module:
image
- package是go代码import的单位,一个module可以覆盖多个package
image
Go mod 嵌套引用不同版本的module,最终使用哪个版本?
答案是:全局使用二者之中最新的版本来运行程序。
比如下面的目录关系:
$ tree
.
├── go.mod
├── go.sum
├── mtest
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── test.go
在test.go
一级的go.mod
里引用一个版本的qmgo
:
require (
github.com/qiniu/qmgo v0.7.6
)
在mtest
一级的go.mod
里使用另一个版本:
require (
github.com/qiniu/qmgo v0.7.7
)
然后在test.go
里调用mtest
包里的方法RunTest()
,此时,go mod
会选择二者中最新的版本来进行编译和运行,也是就说test.go
和mtest.go
里使用的qmgo
都是v0.7.7版本(test.go
一级的go.mod
里的v0.7.6
会被改写成v0.7.7
)。
上例中两个go.mod的引用版本调换,结果依然是使用最新的版本来编译和运行。
Go mod的这个设计无可厚非,只是实际工程中,包的引用是间接的、复杂的,如果某个包的新版本不向前对旧版本兼容,比如新版本删除了一个旧版本的API,那么使用新版本来编译旧版本实现,会导致编译失败。解决方案需要根据实际情况来具体分析,比如替换旧版本module引用(线上更新或者拉私有库修改),回退新版本,某些情况下也可以通过下面的方法同时支持2个版本的存在。
代码如下:
test.go:
package main
import (
"context"
"fmt"
"mtest" // test.go一层的go.mod里,mtest需要replace,上面的go.mod里没有写
"github.com/qiniu/qmgo"
)
func main() {
client, err := qmgo.NewClient(context.Background(), &qmgo.Config{Uri: "mongodb://localhost:27017"})
fmt.Println(err)
defer client.Close(context.Background())
mtest.RunTest()
}
mtest.go:
package mtest
import (
"context"
"fmt"
"github.com/qiniu/qmgo"
)
func RunTest() {
client, err := qmgo.NewClient(context.Background(), &qmgo.Config{Uri: "mongodb://localhost:27017"})
fmt.Println(err)
defer client.Close(context.Background())
}
Go mod如何同时引用多个版本的module
使用replace
即可达成目的
module test
go 1.14
replace github.com/qiniu/qmgo077 => github.com/qiniu/qmgo v0.7.7
require (
github.com/qiniu/qmgo v0.7.6
github.com/qiniu/qmgo077 v0.0.0-00010101000000-000000000000 // 自动生成
)
import (
"context"
"fmt"
"github.com/qiniu/qmgo"
qmgo077 "github.com/qiniu/qmgo077"
)
func main() {
client, err := qmgo.NewClient(context.Background(), &qmgo.Config{Uri: "mongodb://localhost:27017"})
fmt.Println(err)
defer client.Close(context.Background())
client077, err := qmgo077.NewClient(context.Background(), &qmgo077.Config{Uri: "mongodb://localhost:27017"})
fmt.Println(err)
defer client077.Close(context.Background())
}
本文引自这里
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK