0

我使用 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
4

1 回答 1

1

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

在编译时调用宏实现。您尝试访问的实际对象尚不存在(仅Symbol代表它们的语言)。ModuleSymbol这就是为什么当您期望该B对象时会得到一个。

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

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

于 2013-11-09T16:09:13.837 回答