Scala 游览

交叉类型,又名复合类型

语言

有时需要表示对象的类型是其他几个类型的子类型。

在 Scala 中,可以使用交叉类型(或 Scala 2 中的复合类型)来表示,这些类型表现得像交叉的任何部分。

假设我们有两个特征 CloneableResetable

trait Cloneable extends java.lang.Cloneable {
  override def clone(): Cloneable = { // makes clone public
    super.clone().asInstanceOf[Cloneable]
  }
}
trait Resetable {
  def reset: Unit
}
trait Cloneable extends java.lang.Cloneable:
  override def clone(): Cloneable =  // makes clone public
    super.clone().asInstanceOf[Cloneable]
trait Resetable:
  def reset: Unit

现在假设我们要编写一个函数 cloneAndReset,它接收一个对象,克隆它并重置原始对象

def cloneAndReset(obj: ?): Cloneable = {
  val cloned = obj.clone()
  obj.reset
  cloned
}
def cloneAndReset(obj: ?): Cloneable =
  val cloned = obj.clone()
  obj.reset
  cloned

问题在于参数 obj 的类型是什么。如果是 Cloneable,那么该对象可以被 clone,但不能被 reset;如果是 Resetable,我们可以 reset 它,但没有 clone 操作。为了在这种情况中避免类型转换,我们可以指定 obj 的类型既是 Cloneable,也是 Resetable

这种复合类型在 Scala 中写为 Cloneable with Resetable

以下是更新后的函数

def cloneAndReset(obj: Cloneable with Resetable): Cloneable = {
  //...
}

请注意,你可以有多种类型:A with B with C with ...。这与 (...(A with B) with C) with ... ) 是一样的

这种交集类型在 Scala 中写为 Cloneable & Resetable

以下是更新后的函数

def cloneAndReset(obj: Cloneable & Resetable): Cloneable = {
  //...
}

请注意,你可以有多种类型:A & B & C & ...。而且 & 是结合的,因此可以在任何部分周围添加括号,而不会改变含义。

本页的贡献者