类型系统
泛型、Implicit、Type Class。
35 分钟
类型系统
Scala 类型系统支持泛型、型变(covariance / contravariance)、Given 实例(Scala 3 替代 implicit)与 Type Class 模式。对照 /roadmaps/scala「Type System」节点。
学习目标
- 编写泛型类与方法,理解型变注解
- 使用
given/using传递隐式实例 - 用 Type Class 模式扩展第三方类型行为
核心概念
泛型与型变
class Box[+A](val value: A)
trait Writer[-A]:
def write(a: A): Unit
def first[T](xs: List[T]): Option[T] = xs.headOption
val intBox: Box[Int] = Box(42)
val anyBox: Box[Any] = intBox // 协变 +A:子类型向上
def logAll(xs: List[Any]): Unit =
xs.foreach(println)
logAll(List(1, 2, 3)) // List[Int] 是 List[Any] 的子类型(协变)
+A 协变(只读场景);-A 逆变(消费者场景);不变默认。Java 泛型不变,Scala 更灵活但需理解边界。
Given 与 Using(Scala 3)
trait JsonEncoder[A]:
def encode(value: A): String
given JsonEncoder[String] with
def encode(value: String): String = s"\"$value\""
given JsonEncoder[Int] with
def encode(value: Int): String = value.toString
def toJson[A](value: A)(using enc: JsonEncoder[A]): String =
enc.encode(value)
println(toJson("scala"))
println(toJson(2026))
given 定义隐式实例;using 声明隐式参数,调用处自动注入。
Type Class 模式
case class User(name: String, score: Int)
trait Show[A]:
def show(a: A): String
given Show[User] with
def show(u: User): String = s"${u.name}=${u.score}"
def printIt[A](a: A)(using s: Show[A]): Unit =
println(s.show(a))
extension [A](a: A)
def show(using s: Show[A]): String = s.show(a)
printIt(User("alice", 95))
println(User("bob", 88).show)
Type Class 通过隐式实例「事后」为类型添加能力,无需修改原类——类似 Java 中接口适配,但更组合化。
与 Java 对照
| Scala | Java |
|---|---|
型变 +/- | 通配符 ? extends/super |
given / using | 无内置(Spring @Autowired 不同层) |
| Type Class | 外部 Comparator、Apache 工具类 |
扩展方法 extension |