Scala ひと巡り : 複合型 (Compound Types)

ときには、オブジェクトの型が、他の複数の型のサブ型であると表現することが必要になります。Scala では、それをオブジェクト型の論理積である複合型(compound types)の助けを借りて表現できます。

2 つのトレイト Cloneable と Resetable があるとします。

trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone(); this } } trait Resetable { def reset: Unit }

いま、オブジェクトを引数にとってクローンし、オリジナルのオブジェクトをリセットする関数 cloneAndReset を書きたいとします。

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

パラメータ obj の型は何か、という問題が生じます。もしそれが Cloneable なら、オブジェクトはクローンできますがリセットできません。; しかしもし Resetable なら、リセットできますがクローン操作がありません。そのような状況で型キャストを避けるために、obj の型が Cloneable と Resetable の両方であると指定できます。Scala では、複合型を使って Cloneable with Resetable のように書きます。

次は、アップデートした関数です:

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

複合型は複数のオブジェクト型からなり、ただ一つの細別(refinement)を持てます。細別は既存のオブジェクトメンバーのシグニチャを狭めるのに使えます。

一般的な書き方は A with B with C ... { refinement } です。

細別の使用例は、抽象型 [21]に関するページにあります。