Scala Macros:从对象获取vals

时间:2013-11-09 15:42:24

标签: scala reflection scala-macros

我使用scala宏从包中提取所有对象,然后我想从对象中获取一些值:

 package example

 trait A {}
 object B extends A { val test = "test" }

 //macro
 object Macro
   def getVals(packageName: String) = macro getValsImpl

   def getValsImpl(c: Context)(packageName: c.Expr[String]): c.Expr[Unit] = {
     import c.universe._

     val pkg = from.tree match {
      case Literal(Constant(name: String)) => c.mirror.staticPackage(name)
     }

     val objects = pkg.typeSignature.members.collect {
       //get all objects which a subtype of `A`   
       case x if (x.isModule && x.typeSignature <:< typeOf[A]) => x  
     }.toList

     val o = objects(0)

     println(o.test)

     reify {}
   }
 }

但我收到了错误

value test is not a member of c.universe.ModuleSymbol

1 个答案:

答案 0 :(得分:1)

您错误地将编译时工件误认为是实际的运行时值。

在编译时调用宏实现。您尝试访问的实际对象尚不存在(仅代表它们的语言Symbol)。这就是您期望ModuleSymbol对象时获得B的原因。

换句话说,您无法在宏实现中访问B

宏旨在分析,转换和生成代码(表示为ExprTree s)。因此,您可以做的是 - 拥有代表对象的ModuleSymbol - 生成代码,在编译并最终在运行时执行时,将评估该对象。但我不知道这是不是你想要的。