Scala 3 的激动人心的新版本带来了许多改进和新特性。在这里,我们为您提供最重要的更改的快速概述。如果您想深入了解,您可以参考一些参考资料。
- Scala 3 书籍 面向 Scala 语言的新手开发者。
- 语法摘要 为您提供新语法的正式描述。
- 语言参考 详细描述了从 Scala 2 到 Scala 3 的更改。
- 迁移指南 为您提供从 Scala 2 迁移到 Scala 3 所需的所有信息。
- Scala 3 贡献指南 深入探讨编译器,包括修复问题的指南。
Scala 3 的新特性
Scala 3 是对 Scala 语言的彻底改造。在核心方面,类型系统的许多方面都已更改为更加原则化。虽然这也带来了激动人心的新特性(如联合类型),但首先,这意味着类型系统会(更加)少地阻碍您,例如 类型推断 和重载解析得到了很大改进。
新特性:语法
除了许多(较小的)清理之外,Scala 3 语法还提供了以下改进
- 用于控制结构(如
if
、while
和for
)的新“静默”语法(新的控制语法) new
关键字是可选的(也称为 创建者应用程序)- 可选大括号,支持无干扰、对缩进敏感的编程风格
- 将 类型级通配符 从
_
更改为?
。 - 隐式(及其语法)已 彻底修改。
有见地的:上下文抽象
Scala 的一个底层核心概念是(并且在某种程度上仍然是)为用户提供一组强大的功能,这些功能可以组合起来实现强大的(有时甚至是意想不到的)表达能力。例如,隐式功能已被用于建模上下文抽象,表达类型级计算,建模类型类,执行隐式强制转换,编码扩展方法,以及更多。从这些用例中吸取教训,Scala 3 采取了略有不同的方法,专注于意图而不是机制。Scala 3 不提供一个非常强大的功能,而是提供多个定制的语言功能,允许程序员直接表达他们的意图
-
抽象化上下文信息。 使用子句 允许程序员抽象化调用上下文中可用的信息,这些信息应该隐式传递。作为对 Scala 2 隐式的改进,使用子句可以通过类型指定,从而使函数签名摆脱永远不会明确引用的术语变量名。
-
提供类型类实例。 给定实例 允许程序员定义特定类型的规范值。这使得使用类型类更加直接,而不会泄露实现细节。
-
追溯扩展类。在 Scala 2 中,扩展方法必须使用隐式转换或隐式类来编码。相反,在 Scala 3 中,扩展方法 现在直接内置到语言中,从而产生更好的错误消息并改进类型推断。
-
将一种类型视为另一种类型。隐式转换已 从头开始重新设计,作为类型类
Conversion
的实例。 -
高阶上下文抽象。 上下文函数 的全新功能使上下文抽象成为一等公民。它们是库作者的重要工具,允许表达简洁的特定领域语言。
-
编译器提供的可操作反馈。如果编译器无法解析隐式参数,它现在会提供导入建议,这些建议可能可以解决问题。
言简意赅:类型系统改进
除了极大地改进类型推断外,Scala 3 类型系统还提供了许多新功能,为您提供了强大的工具来静态地表达类型中的不变式。
-
不透明类型。在 不透明类型别名 后隐藏实现细节,而不会影响性能!不透明类型取代了值类,并允许您设置抽象屏障,而不会造成额外的装箱开销。
-
交集和并集类型。将类型系统建立在新的基础之上,导致引入了新的类型系统功能:交集类型 的实例,如
A & B
,是同时A
和B
的实例。 并集类型 的实例,如A | B
,是要么A
要么B
的实例。这两种结构都允许程序员灵活地表达继承层次结构之外的类型约束。 -
依赖函数类型。Scala 2 已经允许返回值类型依赖于(值)参数。在 Scala 3 中,现在可以抽象化这种模式并表达 依赖函数类型。在类型
type F = (e: Entry) => e.Key
中,结果类型依赖于参数! -
多态函数类型。与依赖函数类型一样,Scala 2 支持允许类型参数的方法,但没有允许程序员抽象化这些方法。在 Scala 3 中,多态函数类型,如
[A] => List[A] => List[A]
,可以抽象化除了值参数之外还接受类型参数的函数。 -
类型 lambda。在 Scala 2 中需要使用 编译器插件 来表达的内容现在是 Scala 3 中的一流功能:类型 lambda 是类型级别的函数,可以作为(高阶)类型参数传递,而无需辅助类型定义。
-
匹配类型。Scala 3 不再使用隐式解析来编码类型级计算,而是直接支持匹配类型。将类型级计算集成到类型检查器中,可以改进错误消息,并消除对复杂编码的需求。
重新构想:面向对象编程
Scala 一直处于函数式编程和面向对象编程之间的前沿,而 Scala 3 在这两个方向上都突破了界限!上述类型系统变化和上下文抽象的重新设计使函数式编程比以前更容易。同时,以下新功能使面向对象设计结构良好,并支持最佳实践。
- 传递下去。特质更接近于类,现在也可以接受参数,使其作为模块化软件分解的工具更加强大。
- 计划扩展。扩展不打算扩展的类是面向对象设计中长期存在的问题。为了解决这个问题,开放类要求库设计者明确将类标记为开放。
- 隐藏实现细节。实现行为的实用特质有时不应成为推断类型的部分。在 Scala 3 中,这些特质可以标记为透明,从用户(在推断类型中)隐藏继承。
- 组合优于继承。这句话经常被引用,但实施起来很繁琐。Scala 3 的导出子句并非如此:对导入对称,导出子句允许用户为对象的选定成员定义别名。
- 不再有 NPE(实验性)。Scala 3 比以往更安全:显式空值将
null
从类型层次结构中移除,帮助您静态地捕获错误;对安全初始化的额外检查检测对未初始化对象的访问。
内置电池:元编程
虽然 Scala 2 中的宏只是一个实验性功能,但 Scala 3 带有一套强大的元编程工具。该宏教程包含有关不同功能的详细信息。特别是,Scala 3 为元编程提供了以下功能
- 内联。作为基本的起点,内联功能允许在编译时减少值和方法。这个简单的功能已经涵盖了许多用例,同时为更高级的功能提供了入口点。
- 编译时操作。包
scala.compiletime
包含可用于实现内联方法的附加功能。 - 引用的代码块。Scala 3 添加了准引用代码的新功能,为构建和分析代码提供了方便的高级接口。构建将一加一的代码就像
'{ 1 + 1 }
一样简单。 - 反射 API。对于更高级的用例,quotes.reflect提供了更详细的控制来检查和生成程序树。
如果您想了解更多关于 Scala 3 中的元编程,我们邀请您参加我们的 教程。