背景
隐式是Scala 2中的一个主要的设计特色。隐式是进行上下文抽象的基本方式。它们代表了具有多种用例的统一范式,其中包括:
- 实现类型类
- 建立上下文
- 依赖注入
- 表达能力
- 计算新类型,并证明它们之间的关系
此后,其他语言也纷纷效仿,例如 Rust 的 traits 或 Swift 的协议扩展。对于编译期的依赖解析方案,Kotlin 的设计方案也被提上日程,而对 C# 而言是 Shapes 和 Extensions 或对 F# 来说是 Traits。Implicits 也是 Coq 或 Agda 等定理证明器的共同特色。
尽管这些设计使用不同的术语,但它们都是术语推理核心思想的变体: 给定一个类型,编译器会合成一个具有该类型的“canonical”术语。
重新设计
Scala 3 重新设计了 Scala 中的上下文抽象。 虽然这些概念是在 Scala 2 中逐渐“发现”的,但它们现在已广为人知和理解,并且重新设计利用了这些知识。
Scala 3 的设计侧重于 意图 而不是 机制。 Scala 3 没有提供一个非常强大的隐式特性,而是提供了几个面向用例的特性:
-
抽象上下文信息。 使用子句 允许程序员对调用上下文中可用的信息进行抽象,并且应该隐式传递。 作为对 Scala 2 隐式的改进,可以按类型指定 using 子句,从而将函数签名从从未显式引用的术语变量名称中释放出来。
-
提供类型类实例。 给定实例允许程序员定义某种类型的_规范值(canonical value)_。 这使得使用类型类的编程更加简单,而不会泄露实现细节。
-
追溯扩展类。 在 Scala 2 中,扩展方法必须使用隐式转换或隐式类进行编码。 相比之下,在 Scala 3 扩展方法 现在直接内置到语言中,产生了更好的错误消息和改进的类型推断。
-
将一种类型视为另一种类型。 隐式转换已从头开始重新设计,作为类型类
Conversion
的实例。 -
高阶上下文抽象。 上下文函数 的_全新_特性使上下文抽象成为一等公民。 它们是库作者的重要工具,可以表达简洁的领域特定语言。
-
来自编译器的可操作反馈。 如果编译器无法解析隐式参数,它现在会为您提供 导入建议 来解决问题。
好处
Scala 3 中的这些更改实现了术语推理与语言其余部分的更好分离:
- 仅有一种定义 given 的方法
- 仅有一种方法可以引入隐式参数和自变量
- 导入 givens 仅有一种单独的方法,不允许它们隐藏在正常导入的海洋中
- 定义 隐式转换 的方法仅有一种,它被清楚地标记为这样,并且不需要特殊的语法
这些变化的好处包括:
- 新设计避免了特性交织,从而使语言更加一致
- 它使隐式更容易学习和更难滥用
- 它极大地提高了 95% 使用隐式的 Scala 程序的清晰度
- 它有可能以一种易于理解和友好的原则方式进行术语推理
本章将在以下各节中介绍其中的许多新功能。
Contributors to this page:
Contents
- 导言
- Scala 3 特性
- 为什么是 Scala 3 ?
- Scala 的味道
- Hello, World!
- The REPL
- 变量和数据类型
- 控制结构
- 领域建模
- 方法
- 头等函数
- 单例对象
- 集合
- 上下文抽象
- 顶层定义
- 总结
- 类型初探
- 字符串插值
- 控制结构
- 领域建模
- 工具
- OOP 领域建模
- 函数式领域建模
- 方法
- 方法特性
- main 方法
- 总结
- 函数
- 匿名函数
- 函数变量
- Eta 扩展
- 高阶函数
- 自定义 map 函数
- 创建可以返回函数的方法
- 总结
- 打包和导入
- Scala 集合
- 集合类型
- 集合方法
- 总结
- 函数式编程
- 什么是函数式编程?
- 不可变值
- 纯函数
- 函数是值
- 函数式错误处理
- 总结
- 类型和类型系统
- 类型推断
- 泛型
- 相交类型
- 联合类型
- 代数数据类型
- 型变
- 不透明类型
- 结构化类型
- 依赖函数类型
- 其他类型
- 上下文抽象
- 扩展方法
- Given 实例和 Using 语句
- 上下文绑定
- Given 导入
- 实现类型类
- 多元相等性
- 隐式转换
- 总结
- 并发
- Scala 工具
- 使用 sbt 构建和测试 Scala 项目
- worksheet
- 与 Java 交互
- 向 Java 开发者介绍Scala
- Scala for JavaScript Developers
- Scala for Python Developers
- 下一步去哪