gpt4 book ai didi

scala - 通过 Scala 反射查找封闭实例(如果有)

转载 作者:行者123 更新时间:2023-12-01 10:36:55 25 4
gpt4 key购买 nike

我正在尝试使用 Scala 反射来定义特征案例类,它们的同伴可以实现成为“可导出”(例如到 Map[String,Any])和“可导入”。它适用于顶级案例类,但我无法使其适用于内部类。如果我已经拥有封闭实例的句柄,我将知道如何反射性地实例化内部类,我可以将其反射(reflect)到 InstanceMirror,但现在我正在编写一个特性,稍后将由顶级或内部类实现.

只要同伴和构造的实例将共享同一个封闭实例,我就应该能够完成这项工作。但是我一直无法弄清楚如何反射性地确定同伴的封闭实例。

这是我正在尝试做的事情以及发生的问题的简化示例:

import scala.reflect.runtime.universe._;

trait CompanionOfReflectiveConstructable[T] {
def tType : Type;

lazy val mirror : Mirror = runtimeMirror( this.getClass.getClassLoader );
lazy val ctorDecl : Symbol = tType.declaration(nme.CONSTRUCTOR);
lazy val ctor : MethodSymbol = ctorDecl.asMethod;
lazy val tClass : ClassSymbol = tType.typeSymbol.asClass;
lazy val tClassMirror : ClassMirror = mirror.reflectClass( tClass );
lazy val ctorF : MethodMirror = tClassMirror.reflectConstructor( ctor );

// in real-life, i'd derive arguments from ctor.paramss
// but to highlight our issue, we'll assume a no arg constructor
def createInstance : T = ctorF().asInstanceOf[T];
}

trait ReflectiveConstructable;

object Test1 extends CompanionOfReflectiveConstructable[Test1] {
def tType = typeOf[Test1];
}
class Test1 extends ReflectiveConstructable;

class Outer {
object Test2 extends CompanionOfReflectiveConstructable[Test2] {
def tType = typeOf[Test2];
}
class Test2 extends ReflectiveConstructable;
}

这就是发生的事情。
scala> Test1.createInstance
res0: Test1 = Test1@2b52833d

scala> (new Outer).Test2.createInstance
scala.ScalaReflectionException: class Test2 is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror
at scala.reflect.runtime.JavaMirrors$JavaMirror.ErrorInnerClass(JavaMirrors.scala:126)
...

测试 1 效果很好。 Test2 的问题很明显——我需要通过 InstanceMirror 而不是通过我的顶级镜像来获取我的 ClassMirror。 (参见 hereherehere 。)但是,从 CompanionOfReflectiveConstructable 内部,我不知道如何检查我是否是内部实例或我的封闭实例是谁,以有条件地执行适当的工作。有谁知道如何做到这一点?

非常感谢!

最佳答案

我在这里看到的主要问题是您在内部类的伴随对象内使用反射。类 Test2 将定义一个名为 $outer 的字段,该字段包含外部类,但是,从 Test2 伴随对象中,您无法获得创建 Test2 所需的 Outer 实例。我能看到的唯一解决方法是将可选实例传递给你的伴侣特征:

trait CompanionOfReflectiveConstructable[T] {
def tType: Type

def outer: Option[AnyRef] = None

val mirror = runtimeMirror(this.getClass.getClassLoader)
val tClassMirror = outer
.map(a => mirror.reflect(a).reflectClass(tType.typeSymbol.asClass))
.getOrElse(mirror.reflectClass(tType.typeSymbol.asClass))

val ctorF = tClassMirror.reflectConstructor(tType.declaration(nme.CONSTRUCTOR).asMethod)

// in real-life, i'd derive arguments from ctor.paramss
// but to highlight our issue, we'll assume a no arg constructor
def createInstance: T = ctorF().asInstanceOf[T]
}

trait ReflectiveConstructable

class Test1 extends ReflectiveConstructable

object Test1 extends CompanionOfReflectiveConstructable[Test1] {
def tType = typeOf[Test1]
}

class Outer {

object Test2 extends CompanionOfReflectiveConstructable[Test2] {
def tType = typeOf[Test2]
override def outer = Option(Outer.this)
}

class Test2 extends ReflectiveConstructable
}

如果有一种方法可以从 Test2 伴随对象中获取 Outer 实例,那就太好了,但遗憾的是它在运行时不可用。

关于scala - 通过 Scala 反射查找封闭实例(如果有),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15594738/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com