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.x3.9.02026-09-03新的长期支持(LTS)版本线
3.8.x3.8.32026-03-30上一代 Next 版本线
3.3.x3.3.82026-06-10上一代 LTS,仍在维护
2.13.x2.13.182025-11-24Scala 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 setup

Windows 用户到官网下载页获取图形安装包,一路下一步即可,同样会顺带装好 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))   // 7

for 在 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)   // 欢迎回来,Ada

Some / 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))   // 尊贵的 Ada

trait 有点像 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)    // true

given 与 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 PekkoAkka 的开源分支,消息驱动、容错
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 不是一门“谁都要学”的语言,但它是一门投入产出很清晰的语言:在大数据、高并发、金融科技这些领域,它能带来实打实的生产力;而在通用编程上,它能帮你把函数式思维真正用起来。

2026 年的版本生态已经比过去成熟得多,Scala 3.9 LTS 给了新项目一个稳定起点,scala 命令合一也让入门门槛降到了最低。挑一个周末装好环境,从 Hello, Scala 3! 开始,剩下的交给项目和练习。

发表评论

验证码图片,点击可更换