Scala 3 迁移指南

元编程

语言

在编译器阶段(称为宏扩展)执行对宏方法的调用,以生成程序的一部分——抽象语法树。

Scala 2.13 宏 API 与 Scala 2.13 编译器内部紧密相关。因此,Scala 3 编译器无法扩展任何 Scala 2.13 宏。

相比之下,Scala 3 引入了一种新的元编程原则方法,该方法专为稳定性而设计。Scala 3 宏和内联方法通常将与 Scala 3 编译器的未来版本兼容。虽然这是一个无可争议的改进,但这也意味着所有 Scala 2.13 宏都必须使用新的元编程功能从头开始重写。

宏依赖项

即使 Scala 3 模块包含宏定义,它也可以依赖 Scala 2.13 工件,但编译器将无法扩展其宏。当您尝试时,它只会返回一个错误。

 -- Error: /src/main/scala/example/Example.scala:10:45 
 10 |  val documentFormat = Json.format[Document]
    |                            ^
    |Scala 2 macro cannot be used in Scala 3. See https://dotty.epfl.ch/docs/reference/dropped-features/macros.html
    |To turn this error into a warning, pass -Xignore-scala2-macros to the compiler

请注意,使用 -Xignore-scala2-macros 有助于对代码进行类型检查,但会生成不完整的类文件。

当此错误出现在您的项目中时,最终您别无选择,只能升级到宏工件的 Scala 3 编译版本。

移植宏生态系统

虽然处于实验阶段,但 Scala 社区已通过多种方式广泛采用 Scala 2 宏功能:代码生成、优化、符合人体工程学的 DSL...

生态系统的大部分现在依赖于外部库中定义的 Scala 2.13 宏。识别和移植这些库是推动生态系统向前发展的关键。

许多开源宏库的迁移状态可在 此页面 中找到。

重写宏

新的元编程功能与 Scala 2 完全不同。它们包括

在深入重新实现宏之前,你应该问自己

  • 我是否可以使用 inlinescala.compiletime 操作来重新实现我的逻辑?
  • 我是否可以使用更简单、更安全的基于表达式的宏?
  • 我是否真的需要访问 AST?
  • 我是否可以使用 匹配类型 作为返回类型?

你可以通过阅读 Scala 3 中的宏 教程来学习所有新的元编程概念。

交叉构建宏库

你编写了一个很棒的宏库,并且希望它可以在 Scala 2.13 和 Scala 3 中使用。有两种不同的方法,传统的交叉构建技术和更灵活的宏混合技术。

宏混合的好处是,利用 -Ytasty-reader 选项的使用者仍然可以使用你的宏。

你可以通过阅读以下教程来了解它们

其他资源

博客文章和演讲

早期采用者项目

此页面的贡献者