context bounds

1410 ワード

view boundsと同様にcontext bounds(コンテキスト定義)も暗黙的パラメータの構文糖である.context boundsの出現はscala 2である.8バージョンが増加したのは、2.8バージョンが配列タイプの設計(この話題については後述するが、単独で議論する)を修正し、文法的な便利さのために「コンテキスト定義」という概念を導入したことに起因する.
簡単な例を見て、2つの数のサイズを比較するには、暗黙的なパラメータを使用します.
scala> def max2[T](a:T, b:T) (implicit cp : Comparator[T]) = { if (cp.compare(a,b) > 0) a else b }
以下に簡略化できます.
scala> def max[T : Comparator] (a:T, b:T) = { … }
上記のタイプパラメータ宣言T:Comparatorは、Comparator[T]タイプの暗黙的な値が存在することを示す.
など、元maxメソッドではcpという暗黙的なパラメータが使われていますが、省略したらどうやってこのパラメータを使いますか?2つの方法があります.
1つ目は、内部で関数を定義し、暗黙的なパラメータを宣言することです.
scala> def max[T : Comparator] (a:T, b:T) = {
        def inner(implicit c:Comparator[T]) = c.compare(a,b);  

        if(inner>0) a else b 
    }

この方法は外部メソッドの暗黙的なパラメータを隠し、内部ネスト関数に置くだけです.もう1つの推奨方法は、implicitlyメソッドを使用します.
scala> def max2[T : Comparator] (a:T, b:T) = {
        val cp = implicitly[Comparator[T]]

        if( cp.compare(a,b)>0) a else b 
    }

implicitlyはPredefです.scalaで定義されているのは、コンパイラが現在のコンテキストの暗黙的な値を記録する特殊な方法であり、この方法では何らかのタイプの暗黙的な値を得ることができます.
コンテキストにComparator[Int]タイプの暗黙的な値がある場合:
scala> implicit val c = new Comparator[Int]{ override def compare(a:Int, b:Int) = a - b }
では、maxとmax 2の両方に対してInt型のパラメータを正しく実行することができます.
scala> max(1,2) res4: Int = 2
scala> max2(3,2) res5: Int = 3