我想在Scala宏中对x -> y
操作的树进行模式匹配。我正在针对Scala 2.10.4(使用Macro Paradise)和Scala 2.11.x进行交叉编译。我尝试了以下模式,但都没有效果:
arrowTree match {
case q"$x -> $y" => ???
case q"scala.Predef.ArrowAssoc[${_}, ${_}]($x).->$y" => ???
case q"_root_.scala.Predef.ArrowAssoc[${_}, ${_}]($x).->$y" => ???
case q"_root_.scala.Predef.ArrowAssoc($x).->$y" => ???
}
哪种模式可以使这种匹配同时适用于2.10.4和2.11.x?
答案 0 :(得分:2)
在一个完美的世界里,你绝对希望第一个匹配,但并不是那么简单。
每当您在Scala中编写foo -> bar
时,您都会有效地调用foo.->(bar)
之类的方法。当typechecker试图找到一个名为->
的方法时,它会失败,并开始寻找可能将该方法添加到foo的任何含义,并且它通常会找到Predef.ArrowAssoc
,将原始表达式转换为scala.this.Predef.ArrowAssoc[Int](1).->[Int](2)
。
要匹配此项,您可以使用以下模式:
case q"scala.this.Predef.ArrowAssoc[$_]($foo).->[$_]($bar)" =>
这里我们将通配符放在类型参数位置,因为我们现在不关心它们。
在2.10上,模式会略有不同,因为当时隐含的名称不同:
case q"scala.this.Predef.any2ArrowAssoc[${_}]($foo).->[${_}]($bar)" =>
这里的另一个区别是需要在通配符周围使用花括号。 2.10不支持字符串插值器中的$_
语法。