我使用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
答案 0 :(得分:1)
您错误地将编译时工件误认为是实际的运行时值。
在编译时调用宏实现。您尝试访问的实际对象尚不存在(仅代表它们的语言Symbol
)。这就是您期望ModuleSymbol
对象时获得B
的原因。
换句话说,您无法在宏实现中访问B
。
宏旨在分析,转换和生成代码(表示为Expr
和Tree
s)。因此,您可以做的是 - 拥有代表对象的ModuleSymbol
- 生成代码,在编译并最终在运行时执行时,将评估该对象。但我不知道这是不是你想要的。