如何防止Scala在传递给宏实现之前评估参数?

时间:2016-05-03 18:41:20

标签: scala macros

请查看我构建的以下宏(实际上,或多或少复制,来自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。这是因为在后一种情况下,exprfalse而不是21 == 42。如何防止Scala在将参数传递给宏实现之前对其进行评估?

1 个答案:

答案 0 :(得分:1)

我认为,这是Scala中一个众所周知的长期错误:

[SI-6044] Constant folding happens before macro expansion

我相信,这不会在当前的宏实现中修复,因为现在正在对新的元编程框架scala.meta进行工作。