Ich versuche scala Reflexion zu verwenden, um dies zu erreichen:Kann ich eine Instanz der äußeren Klasse mithilfe der Reflektion des inneren Klassentyps abrufen?
val labelBar = Named("bar")
val labelFoo = NamedFunc("foo", (i: Int) => println(i))
val i = newInstance[
labelBar.Var[Int] +
labelFoo.Func[Int => Unit]
]
i.foo(2)
i.bar = 20
Es verwendet eine newInstace Methode ein neues Objekt mit angegebenen Elementen zu erstellen. Um dynamische Member zuzulassen, verwende ich die Dynamic-Klasse der Scala.
newInstance benötigt ein implizites TypeTag-Argument. Var ist eine innere Klassen für die Benannte Klasse:
case class Named(name: String) {
outer =>
class Var[T]() {
def getOuter: Named = outer
}
}
class +[A, B]
Mein Problem ist, dass ich nicht reflectClass auf Typ darstellt innere Klasse verwenden können. Es wirft dies:
scala.ScalaReflectionException: class asVar is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$abort(JavaMirrors.scala:115)
at scala.reflect.runtime.JavaMirrors$JavaMirror.ErrorInnerClass(JavaMirrors.scala:117)
at scala.reflect.runtime.JavaMirrors$JavaMirror.reflectClass(JavaMirrors.scala:183)
Gibt es einen Weg, um es zu umgehen? Hält Scala diese Instanz sogar?
Edit 1: newInstance Methode nimmt nicht die labelFoo Instanz als Argument, so kann ich den Rat in Ausnahmemeldung nicht folgen.
Beachten Sie, dass Sie 'labelFoo' und' labelBar' aus Ihren Argumenten _somehow_ erhalten müssen, oder Sie können nicht auf den Namen und die Funktion zugreifen, die Sie benötigen. Sobald Sie dies getan haben, können Sie dem Rat folgen. Wenn Sie versuchen, "labelBar.Var" irgendwie zu "betrügen", ohne Zugriff auf "labelBar" zu haben und dann "getOuter" aufzurufen, glaube ich nicht, dass es möglich ist. –
@AlexeyRomanov Genau das versuche ich zu erreichen. Wenn ich es richtig verstehe, ist die äußere Klasseninstanz eine "Komponente" des geschachtelten Klassentyps. Ich kann etwas in der Art nicht tun: 'val label: labelBar.Var = neues labelFoo.Var()' Es würde ermöglichen, scala type Parameter zu verwenden, um Werte zu übergeben. – Jaca
Der Wert selbst ist nicht. Sie können das obige nicht tun, auch wenn 'labelBar' und 'labelFoo' den gleichen Wert haben. Das Symbol (oder allgemeiner ein stabiler Pfad) ist und kann wie in meiner Antwort erwähnt durch 'TypeRef' aufgerufen werden. –