在你的代码中,你可以使用公共类型和术语,并调用在不同模块或库中定义的公共方法。只要类型检查器(这是验证代码语义一致性的编译器阶段)能够从包含它们的类文件中读取这些类型、术语和方法的签名,它就能很好地工作。
在 Scala 2 中,签名存储在一种称为 Pickle 格式的专用格式中。在 Scala 3 中,情况略有不同,因为它依赖于 TASTy 格式,而这不仅仅是一种签名布局。但是,为了从 Scala 2.13 迁移到 Scala 3,只有签名是有用的。
Scala 3 Unpickler
第一个好消息是 Scala 3 编译器能够读取 Scala 2.13 Pickle 格式,因此它可以对依赖于使用 Scala 2.13 编译的模块或库的代码进行类型检查。
Scala 3 解释器在社区构建中已经经过多年广泛测试。使用它是安全的。
Scala 3 模块可以依赖 Scala 2.13 工件
作为 sbt 构建,它看起来像这样
// build.sbt (sbt 1.5 or higher)
lazy val foo = project.in(file("foo"))
.settings(scalaVersion := "3.3.1")
.dependsOn(bar)
lazy val bar = project.in(file("bar"))
.settings(scalaVersion := "2.13.11")
或者,如果 bar 是已发布的 Scala 2.13 库,我们可以有
lazy val foo = project.in(file("foo"))
.settings(
scalaVersion := "3.3.1",
libraryDependencies += ("org.bar" %% "bar" % "1.0.0").cross(CrossVersion.for3Use2_13)
)
我们在 sbt 中使用 CrossVersion.for3Use2_13
来解析 bar_2.13
而不是 bar_3
。
标准库
一个值得注意的例子是 Scala 2.13 库。我们确实已经决定 Scala 2.13 库是 Scala 3 的官方标准库。
请注意,标准库是由构建工具自动提供的,您不需要手动配置它。
Scala 2.13 TASTy 读取器
第二个好消息是 Scala 2.13 可以使用 -Ytasty-reader
来使用 Scala 3 库。
支持的功能
TASTy 读取器支持所有传统语言功能以及以下 Scala 3 功能
它部分支持
它不支持更高级的功能
- 上下文函数
- 多态函数类型
- 特征参数
@static
注释@alpha
注释- 函数和元组大于 22 个参数
- 匹配类型
- 联合类型
- 多重相等(除非明确)
- 内联(包括 Scala 3 宏)
- 类型多态(
scala.AnyKind
上限)
Scala 2.13 模块可以依赖 Scala 3 工件
通过使用 -Ytasty-reader
启用 TASTy 读取器,Scala 2.13 模块可以依赖 Scala 3 工件。
作为 sbt 构建,它看起来像这样
// build.sbt (sbt 1.5 or higher)
lazy val foo = project.in.file("foo")
.settings(
scalaVersion := "2.13.11",
scalacOptions += "-Ytasty-reader"
)
.dependsOn(bar)
lazy val bar = project.in(file("bar"))
.settings(scalaVersion := "3.3.1")
或者,如果 bar
是已发布的 Scala 3 库
lazy val foo = project.in.file("foo")
.settings(
scalaVersion := "2.13.11",
scalacOptions += "-Ytasty-reader",
libraryDependencies += ("org.bar" %% "bar" % "1.0.0").cross(CrossVersion.for2_13Use3)
)
类似于 CrossVersion.for2_13Use3
,我们在 sbt 中使用 CrossVersion.for3Use2_13
来解析 bar_3
而不是 bar_2.13
。
互操作性概述
简而言之,我们具有向后和向前兼容性,因此迁移可以逐步进行。
即使其库依赖项尚未移植(宏库除外),您也可以一次移植一个模块的大型 Scala 应用程序。
在过渡期间,您可以在两个 2.13 模块之间插入一个 Scala 3 模块。
只要所有库都解析为单个二进制版本,则允许这样做:您可以在同一类路径中拥有 lib-foo_3
和 lib-bar_2.13
,但不能拥有 lib-foo_3
和 lib-foo_2.13
。
中间带有 2.13 模块的倒置模式也是可能的。
库维护者免责声明
除非您确切地知道自己在做什么,否则不建议发布依赖于 Scala 2.13 库(不包括 scala-library)或反之亦然的 Scala 3 库。原因是为了防止库用户最终在类路径中拥有同一 foo 库的两个冲突版本
foo_2.13
和foo_3
,在某些情况下,此问题无法解决。