假设我正在编写一个 Scala 库 L,它依赖于某个依赖项 D,并由一个程序 P 和另一个程序 Q 使用。P 直接依赖于 D 的 3.2 版,而 Q 直接依赖于 3.3 版。
在这两个版本之间,D 的 API 被打乱,以便获得我在 L 中使用的相同函数,我必须在 L 中编写不同的导入语句。同样,P 依赖于 3.2 特定的行为,而 Q 依赖于 3.3 特定的行为。
现在,通常会发生的是,在编译 P 和 Q 时将选择 D 的最新版本,但这将导致如果 L 依赖于库的 3.3 版,则 P 中断,或者如果 L 依赖于编译 Q,则 L 在编译 Q 时中断在 D 的 3.2 版上。
理想情况下,我希望 P 和 Q 都使用相同版本的 L,因为 L 的公共 API 不会改变。这可能吗?
想到的一般方法是基于依赖解析的L的条件编译。尽管在 JVM 世界中这似乎是无法实现的,因为我们不会传递地编译项目的依赖项,而是依赖于预编译的工件。
如果 D 是 Scala 本身,我现在可以使用 SBT 执行此操作(即与不同的 Scala 版本进行交叉编译,并将特定于版本的代码存在于自己的目录中),但从依赖解析的角度来看,这是一种 hack,因为 SBT 发生了变化工件的名称以允许此交叉编译工作。