Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 发现是否在特定模块类型内声明了类_Scala_Reflection - Fatal编程技术网

Scala 发现是否在特定模块类型内声明了类

Scala 发现是否在特定模块类型内声明了类,scala,reflection,Scala,Reflection,我正在写一个描述结构的DSL。DSL使用类型来引用稍后将实例化的类。我希望强制在特定模块中声明特定类型。这可以是DSL编译后的运行时检查 本质上,我需要从内部类开始访问外部元素,检查它的类型是否正确,并获取对它的引用 如果我得到子类型,我可以通过调用typeSymbol使用反射来获得它的符号,在得到的符号中,我可以调用owner来获得外部类型符号。但是,如果我试图将父对象反映为一个模块(即使父对象是一个模块),它会抛出一个异常 让我们举一个例子: trait TheMixin object T

我正在写一个描述结构的DSL。DSL使用类型来引用稍后将实例化的类。我希望强制在特定模块中声明特定类型。这可以是DSL编译后的运行时检查

本质上,我需要从内部类开始访问外部元素,检查它的类型是否正确,并获取对它的引用

如果我得到子类型,我可以通过调用typeSymbol使用反射来获得它的符号,在得到的符号中,我可以调用owner来获得外部类型符号。但是,如果我试图将父对象反映为一个模块(即使父对象是一个模块),它会抛出一个异常

让我们举一个例子:

trait TheMixin

object TheParent extends TheMixin {
  case class TheChild()
}

object TestDiscoverParent extends App {
  import scala.reflect.runtime.{currentMirror => cm, universe => ru}
  val theChildType = ru.typeOf[TheParent.TheChild]
  val theChildOwner = theChildType.typeSymbol.owner
  println(theChildOwner)
  val theParentModuleSymbol = theChildOwner.asModule
  val theParentRef = cm.reflectModule(theParentModuleSymbol).instance
  println(theParentRef.isInstanceOf[TheMixin])
}
在本例中,将打印行
println(Childowner)

object TheParent
但是对childowner.asModule的调用抛出了一个异常:

线程“main”scala.ScalaReflectionException中的异常:对象该对象不是模块


如何获取对外部对象包装器的引用?

似乎还有一个间接指向,
所有者是一个“模块类”。我不太清楚这意味着什么,可能只是在技术上,每个单例对象背后都有一个实例化一次的类

因此,以下方法似乎有效:

object TestDiscoverParent extends App {
  import scala.reflect.runtime.{currentMirror => cm, universe => ru}
  val theChildType = ru.typeOf[TheParent.TheChild]
  val theChildOwner = theChildType.typeSymbol.owner
  println(theChildOwner)
  require(theChildOwner.isModuleClass)
  val theParentModuleClass = theChildOwner.asClass
  val theParentModuleSymbol = theParentModuleClass.module.asModule
  val theParentRef = cm.reflectModule(theParentModuleSymbol).instance
  println(theParentRef.isInstanceOf[TheMixin])
}

调试代码时,我可以看到clildowner包含一个名为module的私有字段,该字段看起来将提供我期望的结果。不幸的是,它是私有的:(是的,我尝试了asClass.asModule,但它仍在抛出异常,起初我没有意识到。asClass使模块字段可见。正如您指出的那样:val theParentModuleSymbol=theChildOwner.asClass.module.asModule