Go 中两个包依赖了同一个包的不同版本,怎么处理?

2019-01-31 17:20:48 +08:00
 keepeye

如果在项目中依赖了两个包 A 和 B,然后 A 和 B 又同时依赖 C 的不同版本, 这种情况下如何处理呢。

go dep 是不是只支持一层 vendor ? 最新出来的 go module 能否解决这一问题呢?

8054 次点击
所在节点    Go 编程语言
10 条回复
janxin
2019-01-31 17:31:09 +08:00
如果 A/B 没有直接暴露 C,可以直接放在对应的 vendor 下的 A/B 目录下

go module 是可以解决跨版本问题的,不过也要看你的项目中用的 A/B 支持不支持呀...
victoriaraymond
2019-01-31 17:36:12 +08:00
Vendor 和 Module 都可以解决这个问题,Dep 没用过不知道。

但这个问题会导致一个更深层的问题:假设 C 被依赖的两个版本分别 C1 和 C2,C1 和 C2 实际上是会被编译成不同的模块,即 Go 编译器不认为它们是同一份代码。当 C 中有一些全局变量时,这些变量在 C1 和 C2 中各有一份且互相独立,会产生一些奇怪的行为。

Module 会通过尝试把 C1 和 C2 都升级到一个共同的版本来解决这个问题,但有时候因为兼容性的问题,并不能完美升级。
keepeye
2019-01-31 17:38:36 +08:00
@janxin

是这样?
vendor/A/vendor/C
vendor/B/vendor/C

go module 如果 A 和 B 中有 go.mod 文件的话,就能自动处理好么?
keepeye
2019-01-31 17:41:05 +08:00
@victoriaraymond 唉 就没有一个完美的解决办法么
Hellert
2019-01-31 18:25:48 +08:00
gomod 可以解决,import 时可以加上 vN 标记:import github.com/ms/pkg/v2, import github.com/ms/pkg/v3... 这样。
前提是这个包要支持 gomod.

如果不支持可以在 go.mod 中使用 replace 指令重定向到本地文件夹或其它路径。
keepeye
2019-01-31 18:27:58 +08:00
@Hellert 就算导入了不同的版本,go mod 还是只会采纳其中之一来作为最终使用的版本吧
reus
2019-01-31 18:31:22 +08:00
不兼容的版本,就应该有不同的 import path
不遵守这种规则的包,应该抵制,不应该用
Hellert
2019-01-31 18:37:22 +08:00
@keepeye import .../.../vN 标记就是为了解决使用同一包的不同版本问题。
即使同一个 .go 文件中也可以同时使用一个包的不同版本,指定导入别名就行了。

如果包不支持 gomod,你也可以用 replace 指令来实现。
toma77
2019-01-31 20:29:53 +08:00
借楼问一下如何解决 go module 没有代码跳转?
xeaglex
2019-01-31 21:34:48 +08:00
使用别名:

import(
v1 "github.com/v1"
v2 "github.com/v2"
)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/532227

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX