引言
Scala 3(代号 Dotty)是 Scala 语言十年磨一剑的重写:语法更简洁、类型系统更强、学习曲线更平缓。它吸收了大量社区反馈,把 Scala 2 的「高级但难学」改造成「高级且好懂」。
本文聚焦 Scala 3 最关键的六块新特性:enum(更简洁的代数数据类型)、given/using(替代 Scala 2 的 implicit,上下文参数更清晰)、扩展方法(不侵入地给类型加方法)、缩进语法(可选大括号的现代化风格)、交集/联合类型与 Match Types(更强的类型表达),最后给出从 Scala 2 迁移的实战指南。
前置:Scala 基础与类型系统(https://plumephp.com/scala-type-system/、https://plumephp.com/scala-functional-programming/)。
目录
- 1. Scala 3 为什么值得学
- 2. enum:更简洁的 ADT
- 3. given/using:上下文参数新范式
- 4. 扩展方法:无侵入地加行为
- 5. 缩进语法:现代化书写风格
- 6. 交集、联合类型与 Match Types
- 7. 其他值得关注的新特性
- 8. 从 Scala 2 迁移到 Scala 3
- 9. 总结:Scala 3 学习路线图
- 延伸阅读
1. Scala 3 为什么值得学
1.1 定位
| 版本 | 特点 |
|---|---|
| Scala 2 | 功能强大但语法繁琐、implicit 难懂 |
| Scala 3 | 语法简洁、类型系统更强、学习曲线平缓 |
1.2 核心理念
- 更少的「魔法」:隐式转换大幅收紧,given/using 显式清晰。
- 更简单的语法:缩进取代大括号。
- 更强的类型:交集/联合类型、Match Types、opaque types。
2. enum:更简洁的 ADT
2.1 定义
enum Color:
case Red, Green, Blue
enum PaymentMethod:
case Card(number: String, exp: String)
case BankTransfer(account: String)
case Cash
2.2 用 enum 建模
enum OrderStatus(val label: String):
case Created extends OrderStatus("已创建")
case Paid extends OrderStatus("已支付")
case Shipped extends OrderStatus("已发货")
val s = OrderStatus.Paid
println(s.label) // 已支付
2.3 穷尽匹配
def describe(m: PaymentMethod): String = m match {
case PaymentMethod.Card(n, _) => s"卡号 $n"
case PaymentMethod.BankTransfer(_) => "转账"
case PaymentMethod.Cash => "现金"
}
// enum + match:编译器穷尽检查
enum 让 ADT 的定义和用例都大幅简化,是 Scala 3 最受欢迎的新特性之一。
3. given/using:上下文参数新范式
3.1 替代 implicit
Scala 2 的 implicit 承担了「自动传参 + 隐式转换 + 隐式类」多种职责,易混淆。Scala 3 拆成 given(提供实例)与 using(消费实例)。
3.2 基础用法
// 提供实例
given intOrd: Ordering[Int] with {
def compare(a: Int, b: Int): Int = a.compare(b)
}
// 消费实例
def maxOf[A](list: List[A])(using ord: Ordering[A]): A = list.max
maxOf(List(1, 3, 2)) // 自动找到 given intOrd → 3
3.3 语法糖:上下文绑定
// 等价写法:上下文绑定
def maxOf[A: Ordering](list: List[A]): A = list.max
3.4 与 Scala 2 对照
| Scala 2 | Scala 3 |
|---|---|
implicit val | given |
implicit def | given ... with |
隐式参数 (implicit x: T) | (using x: T) |
上下文绑定 [A: T] | 相同 |
4. 扩展方法:无侵入地加行为
4.1 给已有类型加方法
extension (n: Int)
def squared: Int = n * n
def isEven: Boolean = n % 2 == 0
println(4.squared) // 16
println(3.isEven) // false
4.2 泛型扩展
extension [A](list: List[A])
def second: Option[A] = list.drop(1).headOption
List(1, 2, 3).second // Some(2)
List(1).second // None
4.3 与隐式类的对比
Scala 2 用 implicit class,Scala 3 用 extension——更清晰,不易误用。
5. 缩进语法:现代化书写风格
5.1 大括号可省略
// Scala 2 风格
def add(a: Int, b: Int): Int = {
val sum = a + b
sum
}
// Scala 3 缩进风格
def add(a: Int, b: Int): Int =
val sum = a + b
sum
5.2 条件与循环
val result =
if x > 0 then "正"
else "非正"
for i <- 1 to 3 do
println(i)
5.3 混用注意
- 同一段代码不要混用大括号与缩进。
- 缩进是两空格(或与配置一致)。
- IDE(IntelliJ/VSCode)有自动格式化。
6. 交集、联合类型与 Match Types
6.1 联合类型
def handle(x: Int | String): String = x match {
case i: Int => s"整数 $i"
case s: String => s"字符串 $s"
}
handle(42) // 整数 42
handle("hello") // 字符串 hello
6.2 交集类型
trait Readable { def read(): String }
trait Writable { def write(s: String): Unit }
def io(device: Readable & Writable): Unit = {
val data = device.read()
device.write(data)
}
6.3 Match Types:类型层面的分支
type Elem[X] = X match {
case String => Char
case Array[t] => t
case List[t] => t
}
val c: Elem[String] = 'a' // Char
val i: Elem[List[Int]] = 1 // Int
Match Types 让类型系统具备「计算能力」,是 Scala 3 的杀手锏之一。
7. 其他值得关注的新特性
| 特性 | 说明 |
|---|---|
| opaque types | 隐藏底层类型,防误用 |
| 可选参数名(命名实参) | 提升可读性 |
| 更好的推导 | 类型推导更聪明 |
工具库(**、! 非) | 语法糖 |
| 跨版本兼容 | -Xsource:3 迁移模式 |
// opaque types 示例
opaque type UserId = Long
object UserId:
def apply(id: Long): UserId = id
extension (id: UserId) def value: Long = id
val uid = UserId(42)
// uid + 1 // ❌ 编译错误,UserId 是独立类型,防误用
8. 从 Scala 2 迁移到 Scala 3
8.1 迁移步骤
# 1. 确认依赖兼容(用 scala-2.13 迁移检查)
# 2. 项目切到 Scala 3.3(LTS)
# 3. 逐个模块编译,修 implicit 相关错误
# 4. 启用 -Xsource:3 渐进迁移
8.2 常见迁移点
| Scala 2 | Scala 3 |
|---|---|
implicit val x | given x: T |
implicit def | given ... with |
implicit class | extension |
view bounds | 已移除(改用 given) |
符号 => 语法 | =>(旧符号移除) |
8.3 兼容性策略
- Scala 3 可编译 Scala 2.13 写的库(跨版本互操作)。
- 大型项目可分模块渐进迁移。
- 生态大部分库已提供 Scala 3 版本(sbt 里
scalaVersion := "3.3.x")。
// build.sbt
scalaVersion := "3.3.4"
9. 总结:Scala 3 学习路线图
9.1 优先学什么
| 优先级 | 特性 | 收益 |
|---|---|---|
| 高 | enum | ADT 建模更简单 |
| 高 | given/using | 告别 implicit 迷雾 |
| 高 | extension | 优雅扩展 |
| 中 | 缩进语法 | 代码更清爽 |
| 中 | Match Types | 类型层计算 |
| 低 | opaque types | 高级防御 |
9.2 一句话心法
Scala 3 = 更简洁的语法 + 更清晰的上下文 + 更强的类型。它让「学习 Scala 的陡峭曲线」明显变缓,是入手函数式 + 类型安全编程的更好起点。
延伸阅读
- https://plumephp.com/scala-type-system/ — 类型类与 given/using 的底层
- https://plumephp.com/scala-functional-programming/ — 函数式范式在 Scala 3 中的呈现
- Scala 3 官方文档 与 迁移指南
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。