Scala面试题更新 2026-08-05

请解释 Scala 泛型中的协变与逆变概念,并说明它们在泛型类型设计中的具体作用。

技术原理Scala

考察说明

考查对 Scala 类型系统变型(variance)概念的理解及其在泛型设计中的实际意义。

回答思路

  1. 【回答框架 1】协变指类型参数 T 在泛型类型中保持子类型关系,即若 A 是 B 的子类型,则 C[A] 是 C[B] 的子类型,用 +T 声明,适用于只输出 T 的容器,如不可变集合。
  2. 【回答框架 2】逆变指类型参数 T 在泛型类型中反转子类型关系,即若 A 是 B 的子类型,则 C[B] 是 C[A] 的子类型,用 -T 声明,适用于只输入 T 的消费者,如函数参数。
  3. 【回答框架 3】不变则是不声明变型,C[A] 与 C[B] 无子类型关系,适用于既输入又输出的类型,如可变集合。
  4. 【回答框架 4】变型作用在于提升类型安全与代码复用,使泛型类型能更精确地表达子类型关系,避免不安全的类型转换,同时保持类型系统的严格性。
  5. 【回答框架 5】在 Scala 中,变型通过类型参数前的 + 或 - 声明,编译器会检查类型参数的使用位置,确保协变参数只出现在输出位置,逆变参数只出现在输入位置。
  6. 【关键点 1】协变用 +T 声明,保持子类型方向,适合只读容器。
  7. 【关键点 2】逆变用 -T 声明,反转子类型方向,适合函数参数等消费者。
  8. 【关键点 3】不变类型适合可变数据结构,避免类型安全问题。
  9. 【关键点 4】变型声明受编译器位置检查约束,防止不安全使用。
  10. 【易错点 1】混淆协变与逆变的方向,导致子类型关系判断错误。
  11. 【易错点 2】在可变集合上错误使用协变,可能引发运行时类型错误。
  12. 【易错点 3】忽略编译器对变型位置检查的限制,导致编译失败。