Ich habe zwei Züge und ihre Instanzobjekte wie folgt definiert lösen generische Eigenschaft von Namen zur Laufzeit. Forexample, wenn ich "min"
sagen, ich will MinMonoid
Objekt, "avg"
AvgMonoid
Objekt geben sollte, etc. So habe ich Setup folgende:Scala Reflexion
object Test extends App {
val AGGREGATORS_NAME_DICT = Map(
"avg" -> "reflection.AvgMonoid",
"min" -> "reflection.MinMonoid",
"max" -> "reflection.MaxMonoid"
)
val AGGREGATORS_ADT_DICT = Map(
"avg" -> "reflection.Avg",
"min" -> "scala.Double",
"max" -> "scala.Double"
)
val mirror = runtimeMirror(getClass.getClassLoader)
def stringToTypeTag[A](name: String): TypeTag[A] = {
val tpe = mirror.staticClass(name).selfType
TypeTag(mirror, new api.TypeCreator {
def apply[U <: api.Universe with Singleton](m: api.Mirror[U]) =
if (m eq mirror) tpe.asInstanceOf[U#Type]
else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
})
}
def resolve[T](fname: String): Option[Monoid[T] with ADTHelper[T]] = for {
monoidName <- AGGREGATORS_NAME_DICT.get(fname)
adtName <- AGGREGATORS_ADT_DICT.get(fname)
tag <- Option{stringToTypeTag[T](adtName)}
instance <- Option {
mirror
.reflectModule(mirror.staticModule(monoidName))
.instance
.asInstanceOf[Monoid[T] with ADTHelper[T]]
}
} yield instance
}
Das Problem ist jetzt: ich tun kann:
println(resolve("min").get.op(1.0, 2.0))
aber ich kann nicht tun:
val monoid = resolve("min").get
println(monoid.op(1.0, 2.0))
, weil die Art der monoid
in späteren ist Monoid[Nothing] with ADTHelper[Nothing]
. Ich kann den zugrunde liegenden Typ T
von trait Monoid[T]
und trait ADTHelper[T]
mit der von mir entwickelten Methode resolve
nicht lösen. Wie kann ich die resolve
Funktion so ändern, dass sie die Eigenschaften mit Basiswert T
löst ???
Ich weiß, wenn ich mit resolve[Double](...)
aufrufen, wird es funktionieren, aber ich möchte dies in Laufzeit von der AGGREGATORS_ADT_DICT
auflösen.
Danke für den Kommentar.So, es ist wegen Löschen in JVM, oder? Jede andere Möglichkeit, die Sie vorschlagen können, um dies zu erreichen? – bistaumanga
Eigentlich ich w ant, um diese Karten aus der Konfigurationsdatei zu holen. Ich bin mir nicht sicher, ob die Verwendung von Makros funktionieren wird, weil ich möchte, dass diese Merkmale später (außerhalb dieser Codebasis) erweiterbar sind und dies nur die Maps in der Konfigurationsdatei bereitstellt und Objekte bereitstellt, die diese Eigenschaften erweitern. – bistaumanga
Auch wenn JVM keine Typen löschte, mussten die Typargumente noch zur Kompilierzeit für die Typprüfung bestimmt werden. –