0Pricing
Scala for Backend Engineering & Functional Programming · 课时

类型类派生

自动生成实例

类型类派生 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

什么是派生?

类型类派生会根据类型的结构自动生成实例,因此您无需为每个样例类手写重复代码。编译器会根据类型的字段构建实例。

重复样板代码的问题

没有派生功能时,每个新的样例类都需要手动创建实例。如果要为二十个样例类实现 Show,就需要编写二十个几乎完全相同的定义。派生功能消除了这种重复。

先手动组合

在学习自动派生之前,请先注意:您可以根据各字段的实例手动组合出新的实例。这正是派生功能要自动完成的原则。

trait Show[A] { def show(a: A): String }

case class User(name: String, age: Int)

object Main {
  implicit val strShow: Show[String] = s => s
  implicit val intShow: Show[Int] = _.toString

  implicit val userShow: Show[User] = (u: User) =>
    s"User(${strShow.show(u.name)}, ${intShow.show(u.age)})"

  def main(args: Array[String]): Unit = {
    println(userShow.show(User("Ann", 30)))
  }
}

归纳式实例

派生以归纳方式工作:先为基本类型定义实例,然后为积类型(样例类)和和类型(密封特征)组合这些实例。派生实例由各个组成部分构建而成。

Scala 3 的 derives 关键字

Scala 3 支持 derives 子句。带有 derived 方法的类型类,可以通过一个关键字附加到某个类型上。(概念性代码片段;需要可派生的类型类。)

enum Color derives CanEqual:
  case Red, Green, Blue

@main def run(): Unit =
  println(Color.Red == Color.Red)

基于 Mirror 的派生

Scala 3 的派生机制使用 scala.deriving.Mirror,在编译时公开类型的结构(字段类型和名称)。derived 方法会遍历镜像中的元素实例,从而构建出整体实例。

半自动派生

Cats 等库提供半自动派生:您可以针对每个类型,通过 deriveShow 这样的一行代码选择启用,在消除样板代码的同时,让编译时间保持可预测。

自动派生与半自动派生

两种方式:

  • 自动:通过隐式导入,在需要的地方自动生成实例;使用方便,但可能拖慢编译速度。
  • 半自动:您为每个类型显式编写一次派生调用;控制力更强,构建速度更快。

密封特征的派生

对于密封层次结构(即和类型),派生实例会根据值所属的子类型进行分派。下面的手动版本展示了派生机制所自动完成的思路。

trait Show[A] { def show(a: A): String }

sealed trait Shape
case class Circle(r: Int) extends Shape
case class Square(s: Int) extends Shape

object Main {
  implicit val shapeShow: Show[Shape] = {
    case Circle(r) => s"Circle($r)"
    case Square(s) => s"Square($s)"
  }

  def main(args: Array[String]): Unit = {
    println(shapeShow.show(Circle(5)))
    println(shapeShow.show(Square(3)))
  }
}

何时使用派生

在以下情况下可以使用派生:

  • 您有许多数据类型需要同一个类型类(JSON 编解码器、Show、Eq)。
  • 该实例可以根据结构机械地生成。

当行为是定制的,或对性能要求很高时,请手动编写实例。

通用相等性示例

相等性是一个经典的可派生类型类。标准的案例类 == 本身就是一种结构相等性,由编译器为您生成。

case class Coord(x: Int, y: Int)

object Main {
  def main(args: Array[String]): Unit = {
    println(Coord(1, 2) == Coord(1, 2))
    println(Coord(1, 2) == Coord(3, 4))
  }
}

快速检查

检验您对派生机制的理解。

回顾

您学习了类型类派生:

  • 实例通过字段实例或案例实例逐步构建。
  • Scala 3 使用 Mirror 和 derives 关键字。
  • 为方便起见选择自动派生,为了控制力选择半自动派生。
  • 使用它可以消除许多数据类型中的样板代码。

常见问题解答

「类型类派生」课时是免费的吗?

是的 — 「类型类派生」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

「类型类派生」这节课中我会学到什么?

自动生成实例 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「类型类派生」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?

能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 类型类模式
  2. 定义实例
  3. 常见类型类
  4. 类型类派生
← 返回 Scala for Backend Engineering & Functional Programming