2016-06-14 9 views
0

私の質問は、私が次のページで行った検索に基づいています(ただし、私はスカラを初めてやりたいと思って成功しています):スカラー型の汎用型のメソッドを呼び出し、パッケージを反映する

reflection overview

私のコードの目的は、既知のタイプのインスタンスジェネリック型からメソッドを呼び出すことで、ない

class A { 
    def process = { 
    (1 to 1000).foreach(x => x + 10) 
    } 
} 

def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T] 

def perf[T: ru.TypeTag](t: T, sMethodName: String): Any = { 
    val m = ru.runtimeMirror(t.getClass.getClassLoader) 

    val myType = ru.typeTag[T].tpe 

    val mn = myType.declaration(ru.newTermName(sMethodName)).asMethod 

    val im = m.reflect(getTypeTag(t)) 

    val toCall = im.reflectMethod(mn) 

    toCall() 

} 


val a = new A 
perf(a, "process") 

コードは(ワークシート上で)完全にコンパイルが、実行時に次のスタック与える:

scala.ScalaReflectionException: expected a member of class TypeTagImpl, you provided method A$A11.A$A11.A.process 
    at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$ErrorNotMember(test-log4j.sc:126) 
    at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf$1.apply(test-log4j.sc:221) 
    at scala.reflect.runtime.JavaMirrors$JavaMirror.ensuringNotFree(test-log4j.sc:210) 
    at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf(test-log4j.sc:220) 
    at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectMethod(test-log4j.sc:257) 
    at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectMethod(test-log4j.sc:239) 
    at #worksheet#.perf(test-log4j.sc:20) 
    at #worksheet#.get$$instance$$res0(test-log4j.sc:28) 
    at #worksheet#.#worksheet#(test-log4j.sc:138) 

これを修正する方法についてのアイデアを

のアイデアを実証し、次の?特定のオブジェクトを反映するために、すべての

答えて

1

多くのおかげで、あなたはMirror.reflect(obj: T)にそれを渡すために持っていて、何らかの理由でそのtypeTagを渡しています。

class A { 
    def process = { 
    (1 to 1000).foreach(x => x + 10) 
    println("ok!") 
    } 
} 

def perf[T : ClassTag : ru.TypeTag](t: T, sMethodName: String): Any = { 
//  ^modified here 
    val m = ru.runtimeMirror(t.getClass.getClassLoader) 
    val myType = ru.typeTag[T].tpe 
    val mn = myType.decl(ru.TermName(sMethodName)).asMethod 
    val im = m.reflect(t) 
//     ^and here 
    val toCall = im.reflectMethod(mn) 
    toCall() 
} 


val a = new A 
perf(a, "process") 
// ok! 
// res0: Any =() 

:修正するには、TypeTagとともにClassTagを生成するperf署名を変更し、reflectに直接tを渡し、そのようにしなければなりません(注:私も交換が推奨代替品とdeclarationnewTermNameを非推奨)

+0

あなたは上司です! – sam

+0

私は答えを理解していませんでしたが(それは動作します):perf宣言の前に何がありますか。リフレクションに関する構文やドキュメントを理解するためのリファレンスを追加できますか? – sam

+0

もう一度多くの感謝:) – sam

関連する問題