Ich habe einen ziemlich seltenen Anwendungsfall, in dem ein Merkmal von Dritten implementiert wird (denke an eine Plugin-Architektur) und ich möchte ein Feld des Begleitobjekts jedes Merkmals erhalten .Erhalte Feldwert eines Begleitobjekts von TypeTag [T]
Eine einfache Merkmal Implementierung sieht wie folgt aus:
trait Plugin {
val ID: String
}
class HelloWorldPlugin extends Plugin {
val ID = HelloWorldPlugin.ID
}
object HelloWorldPlugin {
val ID = "hello world"
}
In der Plugin-Registry - Ich möchte die ID
jedes Plugin bekommen. Da es sich um eine Art Löschung handelt, scheint Reflection meine einzige Option zu sein. Ich habe versucht, die folgenden ohne Erfolg:
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"
}
}
Aber das Problem dabei ist, dass typeOf[T]
den Klassentyp immer wieder und nicht die Art Module - damit ich die folgenden Laufzeitfehler erhalten:
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)
Was ist der beste Weg, um die ID
Wert für jedes Plugin von seiner TypeTag
zu bekommen?
Ich bin mir nicht sicher, ich verstehe, was Sie vorschlagen mit Bezug auf die 'TypeTag [T]' für jedes Objekt. Ist das nicht das erste, was wir in diesem Ausschnitt machen? Könnten Sie einen Ausschnitt Ihres Vorschlags teilen? – yarinbenado