2011-07-19 16 views
5

次の関数を書いて、与えられたシングルトンのクラスが特性を実装しているかどうかを調べました。パラメータ化された型を持つスカラのリフレクション

/** Given a singleton class, returns singleton object if cls implements T.             
* Else returns None. */ 
def maybeMakeSingletonObj[T: ClassManifest](cls: Class[_]): Option[T] = { 
    try { 
    val m = classManifest[T] 
    val obj = cls.getField("MODULE$").get(m.erasure).asInstanceOf[AnyRef] 

    if (Manifest.singleType(obj) <:< m) Some(obj.asInstanceOf[T]) 
    else None 
    } catch { 
    case e: Exception => None 
    } 
} 

このコードは、次の例で正常に動作します:

trait A 
object B extends A 

assert(maybeMakeSingletonObj[A](B.getClass()) === Some(B)) 

ただし、次の例に失敗します。

trait A[T, R] 
object B extends A[Int, Int] 

assert(maybeMakeSingletonObj[A[_,_]](B.getClass()) === Some(B)) 

任意のアイデア?

+0

エラーを説明するか、少なくとも自己完結型のコードを含めると役立ちます。 –

+0

コードは自己完結型です。失敗は、おそらくmaybeMakeSingletonObjが2番目のケースでいくつかの(B)を返さないということです。それは返されません。マニフェストチェックは、最初のケースと同じように機能しません。また、それは例外がスローされたためではなく、マニフェストチェックのために返されます。 –

+0

これは消去されているのだろうか?私の理解は、パラメタリゼーションがコンパイルを生き残るものではないということです。すなわち、リフレクションで見ることはできません。しかし、間違っている可能性があります。 – Owen

答えて

3

からScalaDoc:型の関係演算子<:<と=:=は、マニフェストではまだ適切に表現されていない型適合の面が数多くあるため、近似値とみなしてください。どうやら、これはそのようなケースの1つです。

関連する問題