Tour of Scala

Составные Типы

Language

Иногда необходимо выразить, то что тип объекта является подтипом нескольких других типов.

В Scala это можно выразить с помощью типов пересечений (или составных типов в Scala 2), которые являются объединением нескольких типов объектов.

Предположим, у нас есть два трейта: Cloneable и Resetable:

trait Cloneable extends java.lang.Cloneable {
  override def clone(): Cloneable = { // создает публичный метод 'clone'
    super.clone().asInstanceOf[Cloneable]
  }
}
trait Resetable {
  def reset: Unit
}
trait Cloneable extends java.lang.Cloneable:
  override def clone(): Cloneable =  // создает публичный метод 'clone'
    super.clone().asInstanceOf[Cloneable]
trait Resetable:
  def reset: Unit

Теперь предположим, что мы хотим написать функцию cloneAndReset, которая берет объект, клонирует его и сбрасывает (Reset) состояние исходного объекта:

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 & .... & является ассоциативным, поэтому скобки могут быть добавлены вокруг любой части без изменения значения.

Contributors to this page: