二进制兼容性
在 Scala 2 中,编译器的不同次要版本可以自由地更改它们在 JVM 字节码中编码不同语言功能的方式,因此编译器的每个次要版本升级都会导致二进制兼容性问题。如果项目有任何 Scala 依赖项,则所有依赖项都需要(交叉)编译到与项目本身使用的相同次要 Scala 版本。相反,Scala 3 具有稳定的 JVM 字节码编码。
除了 class 文件,Scala 3 的编译过程还会生成扩展名为 `.tasty` 的文件。 TASTy 格式是 Scala 代码的中间表示形式,包含有关源代码的完整信息以及类型检查器提供的信息。在生成字节码的过程中,部分信息会丢失,因此 Scala 3 编译器在编译时除了读取 class 文件外,还会读取 TASTy 文件,以了解已编译类中值的精确类型、方法等(尽管也可以仅从 TASTy 文件进行编译)。TASTy 文件通常也与已发布工件中的 class 文件一起分发。
TASTy 格式是可扩展的,但它保留了向后兼容性,并且演变发生在语言的小版本之间。这意味着版本为 `3.x1.y1` 的 Scala 编译器能够读取版本为 `3.x2.y2` 的另一个编译器生成的 TASTy 文件,前提是 `x1 >= x2`(假设考虑两个稳定的编译器版本 - `SNAPSHOT` 或 `NIGHTLY` 编译器版本可以读取旧的稳定格式的 TASTy,但它们之间的 TASTy 版本不兼容,即使编译器具有相同的次要版本;同样,稳定版本中的编译器无法读取不稳定版本生成的 TASTy)。
TASTy 版本号的格式为 `<major_version>.<minor_version>-<experimental_version>`,并且编号与语言版本同步变化,语言次要版本的提升对应 TASTy 次要版本的提升(例如,对于 Scala `3.0.0`,TASTy 版本为 `28.0-0`)。实验版本设置为 0 表示稳定版本,而其他版本则被认为是不稳定/实验性的。TASTy 版本并不严格绑定到数据格式本身 - 标准库 API 的任何更改也需要更改 TASTy 次要版本。