在 GitHub 上编辑此页面

Scala 3 参考

Scala 3 实现了相对于 Scala 2 的许多语言更改和改进。在此参考中,我们讨论设计决策并展示与 Scala 2 相比的重要差异。

目标

语言重新设计由三个主要目标指导

  • 加强 Scala 的基础。使完整的编程语言与 DOT 演算 的基础工作兼容,并应用从该工作中吸取的教训。
  • 使 Scala 更易于使用且更安全。驯服隐式等强大结构,以提供更平缓的学习曲线。消除缺陷和困惑。
  • 进一步提高 Scala 语言结构的一致性和表现力。

为了实现这些目标,语言更改分为七类:(1) 核心结构以加强基础,(2) 简化和 (3) 限制,以使语言更易于使用和更安全,(4) 已删除结构,以使语言更小巧、更规则,(5) 已更改结构,以消除缺陷,并提高一致性和可用性,(6) 新结构,以填补空白并提高表现力,(7) 一种新的、基于原则的元编程方法,用于替换 Scala 2 实验性宏

基本基础

这些新结构直接建模了 DOT 的核心特性、高阶类型以及 SI 隐式解析演算

简化

这些结构使用现有结构,旨在使语言更安全、更易于使用,并促进代码样式的统一。

  • 特质参数 使用更有用的一般结构替换 早期初始化器
  • 给定实例 替换隐式对象和 def,专注于意图而非机制。
  • using 子句 替换隐式参数,避免其歧义。
  • 扩展方法 使用更清晰、更简单的机制替换隐式类。
  • 不透明类型别名 替换大多数值类的用法,同时保证不存在装箱。
  • 顶级定义 替换包对象,删除语法样板。
  • 导出子句 提供一种简单而通用的方式来表达聚合,这可以替换包对象从类继承的先前外观模式。
  • 可变参数拼接 现在在函数参数和模式中使用 xs* 形式,而不是 xs: _*xs @ _*
  • 通用应用方法 允许使用简单的函数调用语法,而不是 new 表达式。new 表达式作为后备保留,用于无法使用创建者应用程序的情况。

除了 早期初始化器 和旧式可变参数模式之外,所有被取代的结构在 Scala 3.0 中仍然可用。计划是弃用它们,并在以后逐步淘汰它们。

值类(被不透明类型别名取代)是一个特例。目前没有弃用值类的计划,因为如果 JVM 本机支持它们,正如 项目 Valhalla 所计划的那样,我们可能会以更通用的形式将它们带回来。

限制

这些结构受到限制,以使语言更安全。

  • 隐式转换:只有一种方法可以定义隐式转换,而不是多种方法,并且可能令人惊讶的隐式转换需要语言导入。
  • 给定的导入:隐式现在需要一种特殊形式的导入,以使导入清晰可见。
  • 类型投影:只有类才能用作类型投影 C#A 的前缀 C。不再支持抽象类型的类型投影,因为它是不健全的。
  • 多重相等:实现“选择加入”方案,以排除使用 ==!= 进行的无意义比较。
  • 中缀:使方法应用语法在所有代码库中保持一致。

不受限制的隐式转换在 Scala 3.0 中仍然可用,但稍后将被弃用并移除。上述列表中其他结构的无限制版本仅在 -source 3.0-migration 下可用。

已删除的结构

建议删除这些结构,而无需用新结构替换它们。删除这些结构的动机是简化语言及其实现。

删除这些结构的日期有所不同。当前状态是

  • 根本未实现
    • DelayedInit、存在类型、弱一致性。
  • -source 3.0-migration 下受支持
    • 过程语法、类阴影、符号文字、自动应用、受限形式的自动元组。
  • 在 3.0 中受支持,稍后将被弃用并逐步淘汰

更改

这些结构已经过更改,以使其更规则、更有用。

  • 结构类型:它们现在允许可插入的实现,这极大地提高了它们的实用性。与现状相比,某些使用模式受到限制。
  • 基于名称的模式匹配:现有的未记录的 Scala 2 实现已以略微简化的形式编纂成文。
  • 自动 Eta 扩展:Eta 扩展现在在没有预期类型的情况下也普遍执行。因此,后缀 _ 运算符变得多余。它将在 Scala 3.0 之后被弃用并删除。
  • 隐式解析:隐式解析规则已清理,使其更有用、更不容易令人惊讶。隐式范围被限制为不再包括包前缀。

旧式隐式解析的大多数方面仍然可以在 -source 3.0-migration 下使用。此列表中的其他更改无条件应用。

新构造

这些是语言的补充,使它更强大或更令人愉快。

  • 枚举为枚举和代数数据类型提供简洁的语法。
  • 参数元组化避免了对元组参数解构使用case
  • 依赖函数类型将依赖方法推广到依赖函数值和类型。
  • 多态函数类型将多态方法推广到多态函数值和类型。当前状态:有一个提案和一个已合并的原型实现,但该实现尚未最终确定(它明显缺少类型推断支持)。
  • 种类多态允许定义在类型和类型构造器上同样工作的运算符。
  • @targetName注释使与用其他语言编写的代码进行交互变得更容易,并为避免名称冲突提供了更大的灵活性。

元编程

以下构造共同旨在将 Scala 中的元编程置于新基础上。到目前为止,元编程是通过宏和库(例如Shapeless)的组合来实现的,而这些库又基于一些关键宏。当前的 Scala 2 宏机制是当前 Scala 2 编译器之上的一个薄层,这使得它们很脆弱,并且在许多情况下无法移植到 Scala 3。

值得注意的是,宏从未包含在Scala 2 语言规范中,并且到目前为止仅在-experimental标志下提供。这并没有阻止它们被广泛使用。

为了启用对宏的大多数用途进行移植,我们正在试验下面列出的高级语言构造。这些设计比 Scala 3.0 提出的其他语言构造更具临时性。在最终发布之前可能仍会有一些更改。稳定元编程所需的特性集是我们的首要任务。

  • 匹配类型允许对类型进行计算。
  • 内联本身提供了对一些简单宏的直接实现,同时也是实现复杂宏的基本构建块。
  • 引号和拼接提供了一种原则性的方法来表达宏和分阶段,并使用一组统一的抽象。
  • 类型类派生提供了 Shapeless 和其他基础库中Gen宏的语言内实现。新实现比宏更健壮、更高效、更易于使用。
  • 按名称上下文参数Shapeless 中提供了更健壮的 Lazy 宏的语言内实现。

另请参阅

提议的语言功能分类是此页面的扩展版本,其中添加了每个语言结构的状态(即成为 Scala 3 的相对重要性,以及何时决定此状态的相对紧迫性)和预期的迁移成本。