5

Go mod 同一个module的多版本问题

 2 years ago
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.
neoserver,ios ssh client

首先,注意区分使用Go mod后,module和package的概念

  • module是go mod的引入单位,go.mod文件里引入的是module:

image

image

  • package是go代码import的单位,一个module可以覆盖多个package

image

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.gomtest.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())
}

本文引自这里


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK