Scala中函数文字与拟文字的匹配
这个问题在动机上与我的类似(尽管它是关于我在一次面试中遇到的一个问题) 我可以很容易地在函数文本上进行模式匹配,而无需使用quasiquotes:Scala中函数文字与拟文字的匹配,scala,macros,scala-macros,scala-quasiquotes,Scala,Macros,Scala Macros,Scala Quasiquotes,这个问题在动机上与我的类似(尽管它是关于我在一次面试中遇到的一个问题) 我可以很容易地在函数文本上进行模式匹配,而无需使用quasiquotes: import scala.reflect.macros.Context import scala.language.experimental.macros object QQExample { def funcDemo(f: Int => String) = macro funcDemo_impl def funcDemo_impl(
import scala.reflect.macros.Context
import scala.language.experimental.macros
object QQExample {
def funcDemo(f: Int => String) = macro funcDemo_impl
def funcDemo_impl(c: Context)(f: c.Expr[Int => String]) = {
import c.universe._
f.tree match {
case Function(ps, body) => List(ps, body) foreach println
case _ => c.abort(
c.enclosingPosition,
"Must provide a function literal."
)
}
c.literalUnit
}
}
其工作原理如下:
scala> QQExample.funcDemo((a: Int) => a.toString)
List(val a: Int = _)
a.toString()
现在假设我想使用Quasikotes更灵活地进行相同类型的匹配。以下内容也将与该函数匹配,并打印我们期望的内容
case q"($x: $t) => $body" => List(x, t, body) foreach println
但是如果我想在模式中指定类型,它不匹配:
case q"($x: Int) => $body" => List(x, body) foreach println
甚至没有以下任何一项:
case q"$p => $body" => List(p, body) foreach println
case q"($p) => $body" => List(p, body) foreach println
case q"..$ps => $body" => List(ps, body) foreach println
case q"(..$ps) => $body" => List(ps, body) foreach println
在将函数文字与quasiquotes匹配时,是否可以指定参数的类型,或者匹配未知数量的参数?对于最新的paradise插件2.10和vanilla 2.11,您可以这样做:
val q"(..$args) => $body" = f.tree
我刚刚用以下宏对其进行了测试。scala
:
import language.experimental.macros
import scala.reflect.macros.Context
object Macro {
def apply(f: Any): Any = macro impl
def impl(c: Context)(f: c.Expr[Any]) = { import c.universe._
val q"(..$args) => $body" = f.tree
println(s"args = $args, body = $body")
c.Expr(q"()")
}
}
object Test extends App {
Macro((x: Int) => x + 1)
}
和Test.scala
:
import language.experimental.macros
import scala.reflect.macros.Context
object Macro {
def apply(f: Any): Any = macro impl
def impl(c: Context)(f: c.Expr[Any]) = { import c.universe._
val q"(..$args) => $body" = f.tree
println(s"args = $args, body = $body")
c.Expr(q"()")
}
}
object Test extends App {
Macro((x: Int) => x + 1)
}
在中,您可以阅读更多关于使用quasiquotes处理函数树的信息 那是一只虫子。上一个代码块中的所有模式都应该适用于单参数匿名函数。当修复程序合并到中时,请按照以下步骤获得通知master@DenShabalin:谢谢!修复程序位于2.11拉取请求队列中。合并后,我将把它向后移植到2.10。我说所有的模式都会起作用也有点错误。您必须在参数上使用括号(即模式2和模式4)@DenShabalin匹配函数类型是否也有效?我成功地匹配了如下
val q“Capture.Capture[$tp]=tree
,树为Capture[()=>R]
,Capture[A=>R]
,Capture[(A,B)=>R]
,等等。接下来我无法匹配val tq”(..$ts)=>$tr tp。请给我一个应该怎么做的提示。@DenShabalin:这不是一个答案吗?