请查看我构建的以下宏(实际上,或多或少复制,来自this精彩的演讲):
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
object SimpleAssert {
def simpleAssert(expr: Boolean): Unit = macro simpleAssertMacro
def simpleAssertMacro(c: Context)(expr: c.Tree): c.Tree = {
import c.universe._
expr match {
case q"$a == $b" =>
q"""
if ($a != $b)
throw new AssertionError($a + " != " + $b)
"""
case _ =>
q"""
Predef.assert($expr)
"""
}
}
}
如果我simpleAssert(x == y)
,它就像一个魅力。但是,如果我执行simpleAssert(21 == 42)
,则模式匹配不会按预期工作,并且正在调用Predef.assert
。这是因为在后一种情况下,expr
是false
而不是21 == 42
。如何防止Scala在将参数传递给宏实现之前对其进行评估?
答案 0 :(得分:1)
我认为,这是Scala中一个众所周知的长期错误:
[SI-6044] Constant folding happens before macro expansion
我相信,这不会在当前的宏实现中修复,因为现在正在对新的元编程框架scala.meta进行工作。