Scala 3 里的新东西

Language

令人振奋的新版 Scala 3 带来了许多改进和新功能。在这里,我们为你提供最重要的变更的快速概述。如果你想深入挖掘,还有一些参考资料供你使用:

Scala 3 里有什么新东西

Scala 3 是对 Scala 语言的一次彻底改造。在其核心部分,类型系统的许多方面都被改变了,变得更有原则性。虽然这也带来了令人兴奋的新功能(比如联合类型),但首先意味着类型系统变得(甚至)不那么碍事了,例如类型推断和 overload resolution 都得到了很大的改善。

新的和闪亮的:语法

除了许多(小的)清理工作,Scala 3 的语法还提供了以下改进:

Opinionated: 上下文抽象

Scala的一个基本核心概念是(在某种程度上仍然是)为用户提供一小部分强大的功能,这些功能可以被组合成巨大的(有时甚至是不可预见的)表达能力。例如,implicit 的特性被用来模拟上下文抽象、表达类型级计算、模拟类型类、执行隐式强制、编码扩展方法等等。从这些用例中学习,Scala 3 采取了一种略微不同的方法,专注于 意图 而非 机制。Scala 3 没有提供一个非常强大的功能,而是提供了多个定制的语言功能,让程序员直接表达他们的意图。

  • Abtracting over contextual information. Using clauses 允许程序员对调用上下文中的信息进行抽象,这些信息应该以隐式方式传递。作为对 Scala 2 implicits 的改进,可以按类型指定 using 子句,从而将函数签名从从未显式引用的术语变量名中解放出来。

  • Providing Type-class instances. Given instances 允许程序员定义某个类型的 规范值 。这使得使用类型类的编程更加简单,而不会泄露实现细节。

  • Retroactively extending classes. 在 Scala 2 中,扩展方法必须使用隐式转换或隐式类进行编码。相比之下,在 Scala 3 中,extension methods现在直接内置于语言中,从而产生更好的错误消息和改进的类型推断。

  • Viewing one type as another. 隐式转换已经被重新设计为类型类Conversion的实例。

  • Higher-order contextual abstractions. context functions全新 功能使上下文抽象成为第一等公民。它们是库开发人员的一个重要工具,允许表达简洁的特定领域语言。

  • Actionable feedback from the compiler. 如果一个隐式参数不能被编译器解决,它现在提供了可能解决这个问题的import suggestions

表达真正的意思: 类型系统改进

除了极大地改进了类型推断,Scala 3 类型系统还提供了许多新的功能,还为你提供了强大的工具来静态地表达类型中的不变量:

  • Enumerations. 枚举已经被重新设计,以便与样例类很好地融合,并形成表达代数数据类型的新标准。

  • Opaque Types. 将实现细节隐藏在opaque type aliases的别名后面,而不需要在性能上付出代价! Opaque types 取代了值类,并允许你建立一个抽象的屏障,而不会造成额外的装箱开销。

  • Intersection and union types. 将类型系统建立在新的基础上,引入了新的类型系统特性:intersection types的实例,如A & B,既是A的实例,也是B的实例;union types的实例,如A | B,是AB的实例。这两种结构都允许程序员在继承层次结构之外灵活地表达类型约束。

  • Dependent function types. Scala 2 已经允许返回类型依赖于(值)参数。在 Scala 3 中,现在可以对这种模式进行抽象,表达dependent function types。在类型F = (e: Entry) => e.Key中,结果类型取决于参数。

  • Polymorphic function types. 与 dependent function types 一样,Scala 2 支持拥有类型参数的方法,但不允许程序员对这些方法进行抽象。在 Scala 3 中,像[A] => List[A] => List[A]这样的polymorphic function types可以抽象出除值参数外还接受 类型参数 的函数。

  • Type lambdas. 在 Scala 2 中需要用编译器插件来表达的东西,现在在 Scala 3 中是原生支持的功能:类型lambdas是类型级别的函数,可以作为(高等类型的)类型参数传递,而不需要辅助类型定义。

  • Match types. Scala 3 提供了对matching on types的直接支持,而不是使用隐式解析对类型级别的计算进行编码。将类型级计算整合到类型检查器中,可以改进错误信息,并消除对复杂编码的需求。

Re-envisioned:面向对象的编程

Scala 一直处于函数式编程和面向对象编程的前沿 – 而 Scala 3 在这两个方向上都推动了边界的发展! 上述类型系统的变化和上下文抽象的重新设计使得 函数式编程 比以前更容易。同时,以下的新特性使结构良好的 面向对象设计 成为可能,并支持最佳实践。

  • Pass it on. Trait 更接近于 class,现在也可以接受参数,使其作为模块化软件分解的工具更加强大。

  • Plan for extension. 在面向对象的设计中,扩展那些不打算扩展的类是一个长期存在的问题。为了解决这个问题,open classes要求库设计者 明确地 将类标记为 open(开放的)。

  • Hide implementation details. 实现功能的工具性的traits有时不应该是推断类型的一部分。在 Scala 3 中,这些traits可以被标记为transparent,(在推断类型中)向用户隐藏继承信息。

  • Composition over inheritance. 这句话经常被引用,但实现起来却很繁琐。Scala 3 的export clauses则不然:与imports对应,export clauses 允许用户为对象的选定成员定义别名。

  • No more NPEs. Scala 3 比以往任何时候都更安全:explicit nullnull移出了类型层次结构,帮助你静态地捕捉错误;safe initialization的额外检查可以检测对未初始化对象的访问。

Batteries Included: 元编程

Scala 2 中的宏只是一个实验性的功能,而 Scala 3 则为元编程提供了强大的工具库。宏教程中包含了关于不同设施的详细信息。特别是,Scala 3 为元编程提供了以下功能:

  • Inline. inline feature允许在编译时化简值和方法。这个简单的功能已经涵盖了许多使用情况,同时也为更高级的功能提供了入口。
  • Compile-time operations. 包scala.compiletime中包含了额外的功能,可以用来实现内联方法。
  • Quoted code blocks. Scala 3为代码增加了quasi-quotation的新功能,这为构建和分析代码提供了方便的高级接口。构建加一加一的代码就像'{ 1 + 1 }一样简单。
  • Reflection API. 对于更高级的用例,quotes.reflect提供了更详细的控制来检查和生成程序树。

如果你想进一步了解 Scala 3 中的元编程,我们邀请你参阅我们的教程

Contributors to this page: