私は非常にまれな使い方をしていますが、サードパーティが独自に実装している(プラグインアーキテクチャを考えています)、各特性のコンパニオンオブジェクトのフィールドを取得したい。 - 私は、各プラグインのID
を取得したいのですが、プラグインレジストリでTypeTag [T]からコンパニオンオブジェクトのフィールド値を取得
trait Plugin {
val ID: String
}
class HelloWorldPlugin extends Plugin {
val ID = HelloWorldPlugin.ID
}
object HelloWorldPlugin {
val ID = "hello world"
}
:
シンプルな形質の実装は次のようになります。私たちは型の消去を扱っているので、Reflectionは私の唯一の選択肢のようです。 私は無駄に次のことを試してみました:
object CompanionReflectionDemo {
import scala.reflect.runtime.{universe => ru}
private lazy val universeMirror = ru.runtimeMirror(getClass.getClassLoader)
def registerPlugin[T <: Plugin](implicit tt: ru.TypeTag[T]) = {
val companionMirror = universeMirror.reflectModule(ru.typeOf[T].typeSymbol.companion.asModule)
val m = universeMirror.reflect(companionMirror.instance)
val field = m.reflectField(ru.typeOf[T].decl(ru.TermName("ID")).asTerm.accessed.asTerm)
field.get
}
def main(args: Array[String]) {
val x = registerPlugin[HelloWorldPlugin]
println(x) // expecting "hello world"
}
}
しかし、ここで問題が
typeOf[T]
は常にクラスタイプとないモジュールタイプを返すことである - ので、私は、次のランタイムエラーを取得:
Exception in thread "main" scala.ScalaReflectionException: expected a member of object HelloWorldPlugin, you provided value org.reflect.HelloWorldPlugin.ID
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$abort(JavaMirrors.scala:115)
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$ErrorNotMember(JavaMirrors.scala:121)
at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf$1.apply(JavaMirrors.scala:214)
at scala.reflect.runtime.JavaMirrors$JavaMirror.ensuringNotFree(JavaMirrors.scala:204)
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf(JavaMirrors.scala:213)
at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectField(JavaMirrors.scala:236)
at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectField(JavaMirrors.scala:233)
at org.reflect.CompanionReflectionDemo$.registerPlugin(Blah.scala:21)
at org.reflect.CompanionReflectionDemo$.main(Blah.scala:26)
何TypeTag
から各プラグインの値をID
にする最も良い方法は?
それぞれのオブジェクトの 'TypeTag [T]'にあなたが示唆しているものを理解しているかどうかは分かりません。これは私たちがこのスニペットでやっている最初のことではありませんか?あなたの提案のスニペットを共有できますか? – yarinbenado