交集类型

& 操作符用于类型时,会创建交集类型。

trait Resettable {
  def reset(): this.type
}
trait Growable[T] {
  def add(x: T): this.type
}
def f(x: Resettable & Growable[String]) = {
  x.reset()
  x.add("first")
}

x值的类型既要是 Resettable 又要是 Growable[String]。交集类型 A & B 用来代替 Scala 2 中形如 A with B 的符合类型(目前 A with B 的形式仍允许,但是将会被弃用删除)。

with 声明的复合类型不同,& 满足交换律:A & BB & A 是等价的。

交集类型 A & B 的成员是 AB 包含的所有成员。例如 Resettable & Growable[String] 具有成员方法 resetadd

如果一个成员同时存在于 AB 中,那么 A & B 中它的类型是 A 中与 B 中它的类型的交集类型。例如,对于下面的代码:

trait A {
  def children: List[A]
}
trait B {
  def children: List[B]
}
val x: A & B = new C
val ys: List[A & B] = x.children

A & Bchildren的类型是 A 中与 B 中它的类型的交集类型 List[A] & Lst[B],因为 List 是协变的,所以能进一步简化为 List[A & B]

人们可能想知道编译器是如何从 List[A]List[B] 中提出 List[A & B] 这个类型的定义。这个问题的答案是不需要。A & B 至少表示对类型的一组约束,在构建值的时候,必须保证所有被继承的成员都被正确的定义了。因此,如果定义了这个继承自 A 以及 B 的类 C,那么在 C 中要定义满足这组约束的方法 children

class C extends A with B {
  def children: List[A & B] = ???
}

results matching ""

    No results matching ""