如何为多个 Scala 版本和不同的依赖项组织代码

How to organize code for multiple scala versions and differents dependencies

我想要 2.12 和 2.13 scala 版本的发布库。但它依赖于另一个仅适用于 2.12 的库。对于 2.13,我为 fast 函数编写了实现:

2.12代码看起来:

import com.dongxiguo.fastring.Fastring.Implicits._ //2.12 only

object Lib {
   val a = fast"hello world"
}

2.13代码看起来:

import mycompat.Implicits._ //2.13 only

object Lib {
   val a = fast"hello world" //my implementation
}

如此不同 - 几个文件中只有 import ...

我不明白如何为不同的 scala 版本组织代码。

有不同的导入是有问题的,因为这意味着你有不同的来源(并且你需要维护它们)。我认为在它自己的原始包中提供缺少的库实现将是更好的解决方案。

//main/scala-2.13/com/dongxiguo/fastring/Fastring/Implicits.scala
package com.dongxiguo.fastring.Fastring
object Implicits {
  //your implementation of fast"Something"
}

只要它在 scala-2.13 文件夹中,它就会被编译并仅用于 scala-2.13。

2.12 和 2.13 版本还需要不同的依赖项:

libraryDependencies ++= {
  CrossVersion.partialVersion(scalaVersion.value) match {
    case Some((2, 12)) => Seq("com.dongxiguo" %% "fastring" % "1.0.0")
    case Some((2, 13)) => Seq()
    case _ => Seq()
  }
}

对于 scala 2.13,您将拥有相同的 Lib 实现而无需任何更改,当 fastring 将发布新的 scala 版本时,您只需删除这些部分。

您还可以创建自己的代理对象,该对象将在 mycompat.Implicits._ 中为 2.12 和 2.13 提供不同的实现。

//main/scala-2.13/mycompat/Implicits.scala
package com.mycompat
object Implicits { /* proxy to fast"Something" from fastring library */ }

//main/scala-2.12/mycompat/Implicits.scala
package com.mycompat
object Implicits { /* your implementation of fast"Something" */ }

这也是个好主意。

基于 lihaoyi and 尝试这样的事情

src/main/scala/example/Hello.scala:

package example

object Hello extends Greeting with App {
  println(greeting)
}

src/main/scala-2.11/example/Greeting.scala:

package example

trait Greeting {
  lazy val greeting: String = "hello-from-2.11.12"
}

src/main/scala-2.13/example/Greeting.scala:

package example

trait Greeting {
  lazy val greeting: String = "hello-from-2.13.1"
}

build.sbt:

crossScalaVersions := List("2.13.1", "2.11.12")

现在sbt ++2.11.12 run输出

hello-from-2.11.12

同时 sbt ++2.13.1 run 输出

hello-from-2.13.1