4Seven Languages in Seven Weeks

Scala

混合范式

trait模式匹配Actor隐式转换

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第4章:Scala(混合范式)

一、导读

1.1 本章学习目标

第4章介绍 Scala——一门融合了面向对象和函数式编程的语言。Scala 运行在 JVM 上,与 Java 完全互操作,同时提供了更强大的类型系统和更简洁的语法。

本章的核心学习目标包括:

  • 理解 Scala 的混合范式:面向对象 + 函数式
  • 掌握 trait 和模式匹配
  • 理解 Scala 的 Actor 并发模型
  • 体验隐式转换的强大与危险

1.2 为什么本章如此重要

Scala 证明了面向对象和函数式编程不是对立的——它们可以和谐共存。Scala 的 trait 比 Java 的接口更强大,模式匹配比 switch 更灵活,隐式转换让 DSL 成为可能。理解 Scala 的设计思想,能帮你在任何语言中更好地融合多种编程范式。

1.3 核心问题引导

Scala 如何融合面向对象和函数式编程?

trait 和 Java 的接口有什么本质区别?

模式匹配为什么比 switch 强大得多?

隐式转换是利器还是陷阱?


二、核心概念详解

2.1 混合范式

scala
// 面向对象
class Person(val name: String, var age: Int) {
  def greet: String = s"Hello, I'm $name, age $age"
}

// 函数式
val numbers = List(1, 2, 3, 4, 5)
val doubled = numbers.map(_ * 2)
val sum = numbers.foldLeft(0)(_ + _)

// 两者结合
class Calculator {
  def compute(op: String, a: Int, b: Int): Int = op match {
    case "+" => a + b
    case "-" => a - b
    case "*" => a * b
    case "/" => a / b
  }
}

2.2 Trait

scala
trait Flyable {
  def fly(): String
}

trait Swimmable {
  def swim(): String
}

trait Singable {
  def sing(): String = "La la la"    // 默认实现
}

// 多重继承
class Duck extends Flyable with Swimmable with Singable {
  def fly(): String = "Flying high!"
  def swim(): String = "Swimming gracefully"
}

val duck = new Duck
println(duck.fly())     // Flying high!
println(duck.sing())    // La la la

2.3 模式匹配

scala
// 强大的模式匹配
def describe(x: Any): String = x match {
  case i: Int if i > 0 => s"Positive integer: $i"
  case s: String => s"String of length ${s.length}"
  case List(1, _*) => "List starting with 1"
  case (a, b) => s"Tuple: ($a, $b)"
  case null => "null"
  case _ => "Unknown"
}

// 代数数据类型
sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(width: Double, height: Double) extends Shape

def area(shape: Shape): Double = shape match {
  case Circle(r) => Math.PI * r * r
  case Rectangle(w, h) => w * h
}

2.4 Actor 模型

scala
import akka.actor._

// 定义消息
case class Greet(who: String)
case class Greeted(greeting: String, who: String)

// 定义 Actor
class Greeter extends Actor {
  def receive = {
    case Greet(who) =>
      println(s"Hello, $who!")
      sender() ! Greeted(s"Hello, $who!", who)
  }
}

// 使用
val system = ActorSystem("HelloSystem")
val greeter = system.actorOf(Props[Greeter], "greeter")
greeter ! Greet("World")

三、实战案例

3.1 案例一:用模式匹配实现表达式求值

scala
sealed trait Expr
case class Num(value: Double) extends Expr
case class Add(left: Expr, right: Expr) extends Expr
case class Mul(left: Expr, right: Expr) extends Expr
case class Neg(expr: Expr) extends Expr

def eval(expr: Expr): Double = expr match {
  case Num(v) => v
  case Add(l, r) => eval(l) + eval(r)
  case Mul(l, r) => eval(l) * eval(r)
  case Neg(e) => -eval(e)
}

def show(expr: Expr): String = expr match {
  case Num(v) => v.toString
  case Add(l, r) => s"(${show(l)} + ${show(r)})"
  case Mul(l, r) => s"(${show(l)} * ${show(r)})"
  case Neg(e) => s"(-${show(e)})"
}

val expr = Add(Mul(Num(3), Num(4)), Num(2))
println(show(expr))    // ((3.0 * 4.0) + 2.0)
println(eval(expr))    // 14.0

四、本章小结

混合范式:Scala 无缝融合面向对象和函数式编程。

Trait:比 Java 接口更强大,支持多重继承和默认实现。

模式匹配:比 switch 强大,支持类型、守卫、解构。

Actor 模型:消息传递的并发模型,避免共享状态。


五、思考与练习

Scala 的 trait 解决了 Java 接口的什么局限?

模式匹配和 Visitor 模式有什么相似之处?

Actor 模型和线程+锁模型相比有什么优势?


4/7Scal
0%