Scala 是一门把面向对象与函数式编程揉进同一套语法、又完整运行在 JVM 上的静态类型语言。它既是大数据生态(Spark、Kafka、Flink)的“母语”,也是金融科技与高并发后端反复选用的工具。2026 年,Scala 3.9 LTS 正式发布,环境要求、工具链和语法都翻开了新的一页。这篇文章按“是什么、为什么、怎么用”三条线索,带你把这门语言从零散印象梳理到能独立上手。
写在前面:2026 年,为什么还值得学 Scala
如果你浏览过招聘网站上的大数据或后端岗位,大概率见过 Scala 的身影。它不像 Python、Java 那样天天被提起,却在几个高价值领域里稳稳占着位置:
- 大数据处理的刚需:Apache Spark 的原生语言就是 Scala。Spark 的 RDD、DataFrame 这些 API 用 Scala 写出来最自然,很多数据管道的参考实现也以它为准。
- 高并发与分布式系统:基于 Actor 模型的并发框架、事件驱动架构、实时流处理,Scala 都有成熟的落地经验,金融风控、实时分析这类场景尤其偏爱它。
- 与 Java 无缝互操作:Scala 编译成 JVM 字节码,可以直接调用海量 Java 库与框架,迁移成本低,团队里懂 Java 的同事也能较快上手。
- 供需结构性失衡:从全球范围看,大数据、金融科技和分布式系统对 Scala 的需求持续增长,但合格的 Scala 工程师供给相对有限,这让有经验的从业者在薪酬上更有议价空间。当然,行情存在明显的区域差异,部分市场的新项目在减少、有人把系统迁回 Java,这一点需要理性看待。
一个更朴素的理由是:Scala 会让你重新理解“类型”“不可变”“抽象”这些概念。哪怕你将来不做 Scala 开发,这套思维方式也会反哺你写 Java、Kotlin、TypeScript 的日常。
Scala 到底是什么:一门“可伸缩”的语言
Scala 这个名字来自 Scalable Language,由 Martin Odersky 于 2001 年在瑞士洛桑联邦理工学院(EPFL)开始设计,2004 年 1 月正式发布。它的设计目标很明确:在 JVM 上做一门既完整继承 Java 生态、又能把函数式编程带入工程主流的语言。
它有四个常被一起提及的身份:
- 静态类型 + 类型推断:类型在编译期确定,但大量场景下编译器能替你推断,写起来并不啰嗦。
- 纯面向对象:一切皆对象,连函数也是值,可以作为参数传递、可以返回。
- 函数式编程:鼓励不可变数据、高阶函数、模式匹配,用表达式而非指令来描述“要什么”。
- 多后端:主战场是 JVM;此外还有编译到 JavaScript 的 Scala.js 和编译到本机代码的 Scala Native,一套语言覆盖多种运行环境。
一个经常被忽略的事实是:函数式与面向对象在这里不是二选一,而是同一套语法里的两种风格,你可以在一个项目里按模块自由取舍。
2026 年版本地图:新项目直接上 Scala 3.9 LTS
Scala 目前同时存在 Scala 2 与 Scala 3 两条线。Scala 2.13 已进入维护模式,新特性只会出在 Scala 3 上,所以新项目没有理由再从 Scala 2 开始。截至 2026 年 10 月,几条版本线的状态如下:
| 版本线 | 最新版本 | 发布日期 | 定位 |
|---|---|---|---|
| 3.9.x | 3.9.0 | 2026-09-03 | 新的长期支持(LTS)版本线 |
| 3.8.x | 3.8.3 | 2026-03-30 | 上一代 Next 版本线 |
| 3.3.x | 3.3.8 | 2026-06-10 | 上一代 LTS,仍在维护 |
| 2.13.x | 2.13.18 | 2025-11-24 | Scala 2 的最后主线 |
几个实用结论:
- 生产项目优先选 LTS。2026 年 9 月发布的 Scala 3.9.0 是官方指定的新 LTS,会长期获得修复,比追最新的“Next”版本更稳。
- 注意 JDK 门槛。Scala 3 从 3.8 开始把最低 JDK 版本提高到 17,而 3.3 LTS 仍兼容 JDK 8。搭环境时别再默认用 JDK 8。
- 工具链要对齐。构建工具 sbt、轻量工具 scala-cli、Mill 都有各自的最低版本要求,混搭过旧版本容易在启动时报错。
- 需要查具体版本时,直接看官方的版本归档页:scala-lang.org/download,兼容性细节可以查官方文档的 JDK 兼容性说明。
环境搭建:十分钟跑通第一行代码
Scala 跑在 JVM 上,所以第一步是准备 JDK 17 或更高版本。从 Scala 3.5 起,原本独立的 Scala CLI 已并入官方 scala 命令,单文件直接运行成为一等公民,不再需要先搭一个完整工程。
安装
Linux 和 macOS 用官方推荐的 Coursier 引导安装:
curl -fL "https://github.com/coursier/coursier/releases/latest/download/cs-x86_64-pc-linux.gz" | gzip -d > cs
chmod +x cs
./cs setupWindows 用户到官网下载页获取图形安装包,一路下一步即可,同样会顺带装好 JVM 和工具链。
第一个程序
新建 hello.scala:
@main def hello(): Unit =
println("你好,Scala!")运行只要一行:
scala run hello.scala不带参数直接敲 scala 命令还能进入 REPL 交互环境,学习语法时随手试非常方便。编辑器方面,VS Code 装官方的 Metals 插件,或者用 IntelliJ IDEA 的 Scala 插件,都能获得补全、类型提示和跳转。
连环境都不想装?打开官方的在线运行时 Scastie,在浏览器里就能写、能跑。
基础语法速览:变量、类型与字符串
先感受一下日常写法。Scala 推荐用 val(不可变)而不是 var(可变),类型能在右侧推断出来时就省略不写:
// val 不可变,var 可变;优先 val
val language: String = "Scala"
var counter = 0
counter += 1
// 类型推断:下面这些都不需要显式写类型
val pi = 3.14159
val names = List("Ada", "Alan", "Barbara")
// 字符串插值
val version = "3.9.0"
println(s"当前语言是 $language,版本是 $version")
println(s"圆周率约等于 ${pi}")
// 多行字符串,用三重引号
val sql =
"""SELECT id, name
|FROM users
|WHERE age > 18""".stripMargin一个值得记住的细节:Scala 里几乎“一切都是表达式”,if、match、代码块都会返回一个值,因此你很少需要先声明一个空变量再去赋值。
val level = if counter > 0 then "有记录" else "空"
val label =
val base = 10
base * 2 // 代码块的最后一行就是返回值函数式编程:Scala 的灵魂
函数式编程在 Scala 里不是装饰,而是解决实际问题的顺手工具。它的两条核心原则是:尽量用不可变数据,以及把函数当成普通值来组合。
先用集合的高阶函数走一遍最常见的三段式——筛选、映射、归约:
val numbers = List(1, 2, 3, 4, 5, 6)
val result = numbers
.filter(_ % 2 == 0) // 只留偶数
.map(_ * 10) // 每个乘 10
.reduce(_ + _) // 求和
println(result) // 120
// 函数是一等公民,可以当参数传进来
def applyTwice(f: Int => Int, x: Int): Int = f(f(x))
val inc = (x: Int) => x + 1
println(applyTwice(inc, 5)) // 7for 在 Scala 里其实是“推导式”,用来组合多个集合非常顺眼:
val pairs = for
a <- List(1, 2, 3)
b <- List(10, 20)
yield a * b
println(pairs) // List(10, 20, 20, 40, 30, 60)再看一个能治好“空指针恐惧症”的惯用法:用 Option 表达“可能没有值”,再配合模式匹配安全地取用。
def findUser(id: Int): Option[String] =
if id == 1 then Some("Ada") else None
val greeting = findUser(1) match
case Some(name) => s"欢迎回来,$name"
case None => "用户不存在"
println(greeting) // 欢迎回来,AdaSome / None 把“有没有值”写进了类型里,编译器会提醒你把两种情况都处理掉,从而把许多运行时异常提前到编译期。
面向对象:case class、trait 与模式匹配
Scala 的面向对象部分和 Java 神似,但少了很多样板代码。最典型的是 case class——一行定义就能自动获得相等判断、hashCode、toString 和 copy。
// case class:一行搞定数据类
case class User(name: String, age: Int)
// trait:定义可复用的行为,可被多个类混入
trait Describable:
def describe: String
class Member(val user: User) extends Describable:
def describe: String = s"${user.name},${user.age} 岁"
// 模式匹配:比 switch 强大得多,还能带条件守卫
def classify(user: User): String = user match
case User(_, age) if age < 18 => "未成年人"
case User(name, _) if name.startsWith("Ada") => "尊贵的 Ada"
case _ => "普通用户"
val m = new Member(User("Ada", 36))
println(m.describe) // Ada,36 岁
println(classify(m.user)) // 尊贵的 Adatrait 有点像 Java 的接口,但可以带字段和具体实现,还能在创建对象时临时混入,这让“用组合代替继承”在 Scala 里非常自然。而模式匹配配合 case class,让“解构数据 + 分情况处理”变成了一段可读性极高的代码。
Scala 3 的几把“新武器”
Scala 3(代号 Dotty)不是小修小补,它在语法和类型系统上做了一批“减负”式的改动。下面挑几个上手即用的讲讲。
枚举与代数数据类型
Scala 3 把枚举做成了语言级特性,还能带参数,直接覆盖了以往需要用一整套继承结构才能表达的代数数据类型。
enum Color:
case Red, Green, Blue
enum HttpStatus(val code: Int):
case Ok extends HttpStatus(200)
case NotFound extends HttpStatus(404)
case BadRequest extends HttpStatus(400)
println(HttpStatus.Ok.code) // 200联合类型
用 | 表示“这个值可能是 A 也可能是 B”,再配合模式匹配做类型收窄,比到处定义包装类清爽得多。
def toText(value: Int | String): String = value match
case i: Int => s"整数:$i"
case s: String => s"文本:$s"
println(toText(42)) // 整数:42
println(toText("Scala")) // 文本:Scala扩展方法
给一个类型“外挂”新方法,不用改它的源码,也不用写隐式转换那种绕弯的写法。
extension (n: Int)
def squared: Int = n * n
def isEven: Boolean = n % 2 == 0
println(5.squared) // 25
println(4.isEven) // truegiven 与 using:类型类的新写法
Scala 2 的隐式(implicit)功能强大但常被吐槽“像魔法”。Scala 3 用 given(提供实例)和 using(请求实例)把它拆得更显式、更易读。类型类的核心思想是:把“能力”作为参数,在编译期传进来。
trait Show[A]:
def show(value: A): String
given Show[Int] with
def show(value: Int): String = s"整数 $value"
given Show[String] with
def show(value: String): String = s"字符串 \"$value\""
def printWith[A](value: A)(using s: Show[A]): Unit =
println(s.show(value))
printWith(42) // 整数 42
printWith("hello") // 字符串 "hello"理解这一个例子,基本就抓住了 Scala 里“类型类”这一抽象模式的门道。想支持新类型,只要再写一个 given 实例,printWith 一行不用改——这就是泛型库 Cats、ZIO 底层的组织方式。
可选缩进语法
Scala 2 满屏的花括号常被拿来和 Python 对比。Scala 3 允许用缩进代替花括号,风格更轻,而且两种写法可以混用,老项目不必强行改造。
// 花括号风格,Scala 2 也兼容
def maxOf(a: Int, b: Int): Int = {
if (a > b) a else b
}
// 缩进风格,Scala 3 特性
def minOf(a: Int, b: Int): Int =
if (a < b) a else b并发与异步:从 Future 到 Actor
在 JVM 上做异步,Scala 的 Future 是最容易上手的一层抽象:它表示“一个将来才会有结果的计算”,可以组合、可以等待。
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration.*
val sum: Future[Int] = Future {
Thread.sleep(1000) // 模拟耗时计算
(1 to 100).sum
}
val total = Await.result(sum, 5.seconds)
println(total) // 5050再往上,是 Scala 生态里最有特色的一块:Actor 模型。每个 Actor 是一个独立的小单元,只通过收发消息来通信,不共享内存,因此天然避开了大量锁的问题,非常适合高并发、分布式的场景。
需要提醒的是,这一领域的框架格局近年有过变化:Akka 在 2022 年改用 Business Source License 后,社区 fork 出了 Apache Pekko,后者已成为 Apache 顶级项目,Play Framework、Flink 等都在开始使用。选型时建议先确认许可证与社区维护状态,再决定用哪一套。
如果追求更强的抽象能力,还有基于函数式的效果系统路线,比如 Cats Effect、ZIO,它们把并发、资源管理、错误处理都统一成可组合的值。不过这类库学习曲线偏陡,建议放在打好基础之后再深入。
Scala 的主战场:生态全景
一门语言值不值得学,很大程度看它的生态。Scala 的生态不算“大而全”,但在几个关键领域相当扎实:
| 领域 | 代表项目 | 说明 |
|---|---|---|
| 大数据计算 | Apache Spark | 原生语言,RDD 与 DataFrame API 的主力写法 |
| 流处理 | Apache Kafka、Apache Flink | 实时数据管道的常见搭配 |
| 并发框架 | Apache Pekko | Akka 的开源分支,消息驱动、容错 |
| Web 后端 | Play Framework、http4s | 全栈式与函数式两种取向 |
| 函数式工具 | Cats、Cats Effect、ZIO | 类型类与效果系统的核心库 |
| 数据访问 | Slick、doobie | 类型安全的数据库访问层 |
| 构建与运行 | sbt、Mill、scala 命令 | 从重型工程到单文件脚本都有覆盖 |
| 测试 | ScalaTest、MUnit | 主流的测试框架 |
如果你的目标是大数据方向,那 Scala 几乎是绕不开的一站;如果是后端方向,把它当作“更强的 Java”来用也完全成立。
一条可执行的“从入门到精通”学习路线
“从入门到精通”最怕的是一上来就啃高级特性。下面给出一个按阶段推进的路线,你可以按自己的节奏拉长或压缩。
第 1 阶段:语法地基
先把变量、类型推断、函数定义、条件与循环、集合的常用操作练熟。目标是能读懂并改写一段普通的 Scala 代码。这个阶段尽量多用 val、少用 var,养成表达式思维。
第 2 阶段:函数式思维
集中攻 map、filter、fold、reduce、for 推导式,理解“函数是一等公民”,并习惯用 Option、Either 代替 null 和异常。这是 Scala 与 Java 手感差别最大的地方,值得多写多练。
第 3 阶段:类型系统与抽象
学习 case class、trait、泛型、协变逆变、模式匹配,再进入 Scala 3 的 given / using 与类型类。当你第一次亲手实现一个类型类实例时,往往会有一层“原来抽象是这么回事”的开窍感。
第 4 阶段:并发与工程化
掌握 Future 的组合式异步写法,了解 Actor 模型的思想,同时把构建工具(sbt 或 Mill)、依赖管理、单元测试跑顺。能独立搭起一个可编译、可测试的小工程,是这一阶段的验收标准。
工程化的完整工作流可以这样配置:构建工具三选一(sbt 最老牌、Mill 更现代、单文件场景 scala 命令全覆盖),测试用 MUnit 或 ScalaTest,格式化交给 scalafmt,CI 里再配上版本升级工具。
第 5 阶段:选定方向深耕
到这一步就该收窄战线了:想做数据就往 Spark、Flink 走,想做后端就往 Web 框架和数据库访问层走,想做函数式就往 Cats Effect、ZIO 走。与其样样都碰,不如在一个方向上做出能拿得出手的项目。
新手最容易踩的五个坑
- 把 Scala 2 和 Scala 3 的语法混着写:两者的隐式、枚举、入口方法都不一样。定好版本再学,别让搜索结果把你带偏。
- 用写 Java 的方式写 Scala:大量
var加while循环,能跑但失去了这门语言的价值。刻意练习不可变与高阶函数。 - 把隐式当玄学跳过:Scala 2 的
implicit确实绕,但 Scala 3 的given/using已经清晰很多,值得正面理解,否则永远停在“能跑就行”。 - 忽略构建工具:真正写项目后,sbt 或 Mill 是绕不过去的。早点熟悉依赖声明与编译流程,比事后补课轻松。
- 一上手就啃重库:Cats Effect、ZIO 这类效果系统很强,但没有扎实的集合与类型基础,很容易被抽象劝退。按路线来,别跳级。
生态与就业:诚实版现状
Scala 的基本盘在大数据:Spark 体系的数据工程岗位是它最稳定的就业出口,金融和通信行业的批处理、流计算系统里也很常见。通用后端领域,Play 与 Pekko 技术栈岗位存在但数量远少于 Java 和 Kotlin;头部公司里,X(原 Twitter)2023 年起迁离 Scala 属于个别公司的选型变化,不必过度解读。
简单说:为了大数据或函数式思维,学它很值;为了泛用后端岗位,Java 和 Kotlin 更现实。
学习资源
- Scala 官网:下载、新闻与版本公告的第一入口。
- 官方文档站:从 Tour of Scala 到 Scala 3 Book,官方入门教程系统且免费。
- Scala 3 Book:零基础友好,适合作为第一本书。
- Hands-on Scala 在线免费版:以实战项目驱动的整本书,读完能直接干活。
- Coursera:Scala 函数式编程专项:EPFL 出品,作者就是 Scala 之父 Odersky。
- Scala 3.9 LTS 发布公告:了解最新 LTS 的变化与迁移指南。
- scala 命令合一公告:Scala 3.5 起 CLI 并入官方命令的来龙去脉。
- Apache Spark 与 Apache Pekko:两大最主流的应用生态,进阶后值得各跑一个示例。
结语
Scala 不是一门“谁都要学”的语言,但它是一门投入产出很清晰的语言:在大数据、高并发、金融科技这些领域,它能带来实打实的生产力;而在通用编程上,它能帮你把函数式思维真正用起来。
2026 年的版本生态已经比过去成熟得多,Scala 3.9 LTS 给了新项目一个稳定起点,scala 命令合一也让入门门槛降到了最低。挑一个周末装好环境,从 Hello, Scala 3! 开始,剩下的交给项目和练习。