在宏中引入用户命名的变量

Introducing variables named by user in a macro

所以我想定义一个引入几个变量作为变量声明的宏,这样名称由宏的用户定义。

说我希望能够写出类似下面的东西

foldOver(0)(hd, rest)(List(1, 2, 3)) {
  hd + rest
}

我对如何做到这一点的第一个想法是制作变量参数并以某种方式手动检查它们。我玩弄了如下定义。

def foldOver[A, B](z : B)(next : A, acc : B)(lst : List[A])(f : B): B = macro foldOverImpl[A, B]
def foldOverImpl[A : c.WeakTypeTag, B : c.WeakTypeTag]
                (c: Context)
                (z : c.Expr[B])(next : c.Expr[A], acc : c.Expr[B])
                (lst : c.Expr[List[A]])
                (f : c.Expr[B]): c.Expr[B] = {
    import c.universe._
    (next, acc) match {
      case (TermName(nextName), TermName(accName)) => {
        c.Expr[B](q"""{
          <do whatever here>
        }""")
      }
      case otherwise => {
        throw new Exception("the 'next' and 'acc' variables must be term names")
      }
    }
}

但是当我使用顶部显示的宏时,出现错误,提示无法在程序中找到这些变量名。嗯,不应该,我希望在宏内部而不是包含上下文中声明它们。

那么,有没有办法从用户那里接收名称并使用这些名称在宏中声明变量?

不可能在 def 宏中执行此操作,因为 def 宏需要在扩展之前对其所有参数进行类型检查。宏注释没有此限制,但它们具有不同的语法,可能不适合您的用例。