由于 Scala 2.13 和 Scala 3 之间的互操作性,Scala 3 的迁移变得更加容易,如 兼容性参考 页面中所述。
但是,在将 Scala 2.13 项目移植到 Scala 3 之前,必须满足一些先决条件
- 它不得依赖尚未移植到 Scala 3 的宏库。
- 它不得使用在 Scala 3 中没有等效项的编译器插件。
- 它不得依赖
scala-reflect
。
以下段落解释了如何检查这些先决条件,以及在不满足这些先决条件的情况下可以采取哪些措施。
如果你已准备好继续迁移,则可以直接跳转到 sbt 迁移教程。
宏依赖项
宏库是一个公开宏方法的 Scala 库。
这些库往往更具表现力,因此在 Scala 2 中被广泛使用。我们可以举出一些例子
但是 Scala 3 编译器无法扩展 Scala 2.13 宏。因此,在跳转到 Scala 3 之前,您应该确保您的项目不依赖于尚未移植的宏库。
您可以在 Scala 宏库 页面中找到许多宏库的迁移状态。希望在您阅读这些内容时,许多宏库已经移植。
对于项目中的每个此类宏依赖项,您需要将其升级到跨版本——在 Scala 2.13 和 Scala 3 上都可用的版本。
我们来看一个快速示例。
对 "scalatest" %% "scalatest" % "3.0.9"
的依赖项必须升级,因为
scalatest
API 基于一些宏定义。3.0.9
版本未针对 Scala 3 发布。
我们可以将其升级到版本 3.2.7
,该版本在 Scala 2.13 和 Scala 3 中跨发布。
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.7"
编译器插件
Scala 2 编译器插件与 Scala 3 不兼容。
编译器插件通常通过以下设置之一在 build.sbt
文件中配置
// build.sbt
libraryDependencies +=
compilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)
某些编译器插件也可以由 sbt 插件自动添加。
您可以通过查看项目的编译器选项来查找所有已配置的编译器插件。
在上述示例中,我们可以看到使用了两个编译器插件:wartremover 和 semanticdb。对于每个此类插件,我们需要检查是否有备用解决方案,或者我们需要禁用它。
下面给出了对最常用的编译器插件的备用解决方案。
SemanticDB
对 SemanticDB 的支持现已内置到 Scala 3 编译器中
-Ysemanticdb
选项激活 semanticDB 文件的生成。-semanticdb-target
选项可用于指定 semanticDB 文件的输出目录。
sbt 能够使用此单一设置自动配置 SemanticDB:semanticdbEnabled := true
。
Scala.js
Scala 3 中的 Scala.js 编译不再依赖于编译器插件。
要编译 Scala.js 项目,可以使用 sbt-scalajs
插件版本 1.5.0
或更高版本。
// project/plugins.sbt
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.0")
Scala Native
自 v0.4.3 起,Scala Native 支持 Scala 3。
Scala Native 支持的 Scala 3 最低版本是 3.1.0,这是因为 Scala 3.0.x 中存在致命障碍
Kind Projector
-Ykind-projector
选项下,Scala 3 支持 Kind Projector 语法的子集。
此外,我们现在有了以下特性,使得在许多情况下不需要 kind-projector
您可以在其 专门页面 中了解有关 Kind Projector 迁移的更多信息。
运行时反射
scala-reflect
不会移植到 Scala 3,因为它公开了 Scala 3 中不存在的 Scala 2 编译器内部结构。
如果您的项目依赖于 scala-reflect
,或使用 Manifest
类的实例,则无法由 Scala 3 编译器编译。要解决这种情况,您可以尝试使用 Java 反射或 Scala 3 元编程特性 重新实现代码的相应部分。
如果 scala-reflect
以传递方式添加到您的类路径中,您可能需要升级引入它的依赖项。