我是scala宏的新手,花了几天的时间尝试编写我的第一个宏。
我对准引用串联有问题。
这里有一个case子句列表,让我们说以下内容:
val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil
我需要从中构建一个部分函数。
问题是我不知道如何将其粘贴到最终的准报价中。
文档说我应该做这样的事情:
q"{ case ..$cases }"
但是如果我这样做是行不通的。
有没有办法从这样的列表构建PartialFunction?
谢谢你的帮助。
最佳答案
以下对我而言适用于2.11.2:
import scala.reflect.macros.Context
object Macros {
def partial: PartialFunction[Int, Int] = macro partialImpl
def partialImpl(c: Context): c.Expr[PartialFunction[Int, Int]]= {
import c.universe._
val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil
val pf = q"{ case ..$cases } : PartialFunction[Int, Int]"
c.Expr[PartialFunction[Int, Int]](pf)
}
}
然后,您可以调用
Macros.partial(1)
或Macros.partial.isDefinedAt(2)
。请注意,为了使这项工作有效,我必须在准引用
PartialFunction[Int, Int]
中显式使用q"{ case ..$cases } : PartialFunction[Int, Int]"
。没有显式的类型定义,它是行不通的(否则假定为PartialFunction[Any, Int]
)。Here是部分函数的准引用语法的规范。它可以用作纯语法树,但显然除非宏类型明确,否则无法将其解释为除
PartialFunction[Any, T]
之外的类型化表达式。
关于Scala准引用串联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30343289/