あるプログラマの日記

プログラマのメモ、出来事、考えたこと、勉強とかの雑記

上限境界、下限境界

上限境界、下限境界を指定して型パラメータまたは抽象型の型に制限をつけることができる。

上限境界(upper bounds)

[T :< Parent]

  • T は、型 Parent のサブ型(子の型)を参照
  • 型パラメータまたは抽象型の型のスーパー型(親の型: Parent)から許可
  • サブ型への境界は Nothing まで。つまり型階層の一番下
trait Hoge {
  val item: String
  val t: String
  def getId: String = item + t
}

class Foo(val item: String) extends Hoge {
  val t = "foo"
}

class Bar(val item: String) extends Hoge {
  val t = "bar"
}

object Foo {
  def checkType[T <: Hoge](a: T, b: T) = a.t == b.t
  def checkItem[T <: Hoge](a: T, b: T) = a.item == b.item
  def check[T <: Hoge](a: T, b: T) = a.getId == b.getId

  def main(argv: Array[String]) {
    val foo1 = new Foo("2012")
    val foo2 = new Foo("2011")
    val bar = new Bar("2012")
    println(checkType(foo1, foo2))
    println(checkType(foo1, bar))
    println(checkItem(foo1, foo2))
    println(checkItem(foo1, bar))
    println(check(foo1, foo2))
    println(check(foo1, bar))
  }
}


結果

$ scala Foo
true
false
false
true
false
false

下限境界(lower bounds)

[T >: Sub]

  • T は、型 Sub のスーパー型(親の型)を参照
  • 型パラメータまたは抽象型の型はサブ型(子の型: Sub)までを許可
  • スーパー型への境界は Any まで。つまり型階層の一番上
class Foobar[+T](elem: T, elems: Foobar[T]) {
  def add[P >: T](item: P): Foobar[P] = new Foobar(item, this);
  def getList[P >: T](tail: List[P]): List[P] = {
    elems match {
    case null => elem :: tail
    case _ => elems.getList(elem :: tail)
    }
  }
}

object Foobar {
  def main(argv: Array[String]) {
    val foobar = new Foobar[AnyVal](0, null)
    val foobar2 = foobar.add(1).add(2).add(3).add(4);
    foobar2.getList(Nil).foreach(println)
  }
}

結果

$ scala Foobar
0
1
2
3
4