【Scala】 変位パラメータの境界「下限境界」「上限境界」
環境 Scala 2.11.6 CentOS7.0
「Scalaスケーラブルプログラミング」(コップ本)メモ
■ 下限境界、上限境界(第19章)
簡単にいうと、型パラメーターに制限をつける機能
▽下限境界 型パラメータが、どのサブクラスまで許可されるかを示す
▽上限境界 型パラメータが、あるクラスをミックスインしている事を示す
下限境界
以下のようにクラスを用意する。
class Base {} class Super extends Base {} class Sub extends Super {} class Item[+T](item: T) {} class Foo [U](foo: Item[U]) {} class Bar [U >: Super](bar: Item[U]) {}
最後のclass Barの[U >: Super]
が下限境界。
通常class Fooのように境界がない場合、
scala> val isub = new Item(new Sub) isub: Item[Sub] = Item@3c419631 scala> val fsub = new Foo(isub) fsub: Foo[Sub] = Foo@3427b02d
のように、Foo[Sub]型のインスタンスが作成される。
class Barで同様の事をすると
scala> val isub = new Item(new Sub) isub: Item[Sub] = Item@3c419631 scala> val bsub = new Bar(isub) bsub: Bar[Super] = Bar@c8c12ac
Item[Sub]型を与えても、Item[Super]型に変換される。
具体的には、class Buf[U >: T]
となっているとき、UにTのさらにサブ型の値を与える事はできない。
UがTのサブ型の場合は、暗黙的にT型に変換される。
UがTのサブ型でも、直接的なスーパー型でもない場合は、UとTの共通のスーパー型に変換される。
scala> new Bar(new Item("anyref":AnyRef)) res3: Bar[AnyRef] = Bar@291caca8 scala> new Bar(new Item("string":String)) res4: Bar[Object] = Bar@32910148
上限境界
ある型パラメータが、特定の型クラスをミックスインした型の必要があるとき、それを上限境界という形で指定できる。
class Item(val str: String) extends Ordered[Item] { // 抽象メソッドを実装する def compare(that: Item) = { if(this.str > that.str) 1 else 0 } } class Item2 {} class Foo [U <: Ordered[U]](foo: U) {} scala> new Foo(new Item("string")) res6: Foo[Item] = Foo@2e77b8cf // Item2はOrderedをミックスインしていない scala> new Foo(new Item2) <console>:10: error: inferred type arguments [Item2] do not conform to class Foo's type parameter bounds [U <: Ordered[U]] new Foo(new Item2) ^ <console>:10: error: type mismatch; found : Item2 required: U new Foo(new Item2) ^
上限境界、下限境界を同時に設定する
以下のように書く。順番は下限、上限の順。
class Bar [U >: Super <: Base](bar: U) {}