【发布时间】:2013-08-27 14:39:30
【问题描述】:
这是一个简化的示例,但问题仍然存在。
我想使用宏(基于 scala 的伪代码)来实现这一点:
(a: Int) => {
val z = "toShort"
a.z
}
如果我具体化它,我会得到类似的东西:
Function(
List(
ValDef(
Modifiers(Flag.PARAM),
newTermName("a"),
Ident(scala.Int),
EmptyTree
)
),
Block(
List(
ValDef(
Modifiers(),
newTermName("z"),
TypeTree(),
Literal(Constant("toShort"))
)
),
Apply(
Select(
Ident(newTermName("a")),
newTermName("toShort")
),
List()
)
)
)
我不知道如何访问一个值,然后将其用作 TermName。
我尝试用newTermName(c.Expr[String](Select(Ident(newTermName("z")))).splice) 替换newTermName("toShort"),但编译器似乎不喜欢:
宏扩展期间的异常: java.lang.UnsupportedOperationException: 你调用的函数没有被 > 编译器拼接。 这意味着涉及跨阶段评估,需要显式调用。 如果您确定这不是疏忽,请将 scala-compiler.jar 添加到类路径中, 导入
scala.tools.reflect.Eval并改为调用<your expr>.eval。
我也按照编译器的建议尝试了“eval”:newTermName(c.eval(c.Expr[String](...)),但都没有成功。
我怎样才能将像Select(Ident(newTermName("z"))) 这样的树(这是对本地val 值的访问)转换为a Name 一个可以用作newTermName 参数的字符串?有可能吗?
更新:
这是gist给你带来的真正问题!
提前致谢,
【问题讨论】:
-
newTermName("z")已经返回Name。我不明白那个有什么问题。 -
您的意思是要从现有树中提取它吗?喜欢
val Select(Ident(name)) = tree? -
我想用
val z的值作为newTermName方法的参数。Select(Ident(newTermName("z")))是对值的访问,然后是:newTermName("<value of z>")。所以可以这样做:a.toShort.
标签: scala macros scala-macros