Scala 从编译到运行时具体化ValDef
我想将ValDef具体化到运行时,但我不直接工作。如果我将ValDef封装到一个块中,那么一切都会完美工作,如以下示例所示:Scala 从编译到运行时具体化ValDef,scala,reflection,scala-macros,Scala,Reflection,Scala Macros,我想将ValDef具体化到运行时,但我不直接工作。如果我将ValDef封装到一个块中,那么一切都会完美工作,如以下示例所示: case class Container(expr: Expr[Any]) def lift(expr: Any): Container = macro reifyValDef def reifyValDef(c: Context)(expr: c.Expr[Any]): c.Expr[Container] = { import c.universe._ ex
case class Container(expr: Expr[Any])
def lift(expr: Any): Container = macro reifyValDef
def reifyValDef(c: Context)(expr: c.Expr[Any]): c.Expr[Container] = {
import c.universe._
expr.tree match {
case Block(List(v: ValDef), _) =>
val asBlock = q"{$v}"
val toRuntime = q"scala.reflect.runtime.universe.reify($asBlock)"
c.Expr[Container](q"Container($toRuntime)")
}
}
lift {
val x: Int = 10
}
如果我直接使用v,而不是将其包装成块,我会得到错误:
Error:(10, 11) type mismatch;
found :
required: Any
Note that extends Any, not AnyRef.
Such types can participate in value classes, but instances
cannot appear in singleton types or in reference comparisons.
val x: Int = 10
^
错误:(10,11)类型不匹配;
发现:
必填项:任何
注意,它扩展了Any,而不是AnyRef。
此类类型可以参与值类,但不包括实例
不能出现在单例类型或引用比较中。
val x:Int=10
^
它只是没有直接与ValDefs一起工作,还是我的代码有问题?这是反射API中已知的问题之一。从技术上讲,定义不是表达式,因此不能直接将其作为参数传递给函数。将定义包装在块中是寻址块的正确方法 错误消息当然令人困惑,但它确实有一些扭曲的含义。为了表明定义本身没有类型,相应的
树的tpe
字段设置为NoType
。然后根据Any
检查宏参数的类型,检查失败(因为NoType
是一种特殊类型,与任何类型都不兼容),因此会打印标准错误消息。笨拙的打印输出是预打印程序在这种奇怪情况下的行为的产物