我想在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中,什么模式可以使这个匹配工作?
在一个完美的世界里,你肯定希望第一个匹配,但这并不是那么简单。
当你在Scala中编写foo -> bar
时,你有效地调用了foo.->(bar)
这样的方法。当typechecker试图找到一个名为->
的方法时,它失败了,并开始寻找任何可以将该方法添加到foo的隐式,它通常会找到一个将原始表达式转换为scala.this.Predef.ArrowAssoc[Int](1).->[Int](2)
的Predef.ArrowAssoc
。
可以使用下面的模式:
case q"scala.this.Predef.ArrowAssoc[$_]($foo).->[$_]($bar)" =>
这里我们把通配符放在类型参数的位置,因为我们现在不关心这些。
在2.10版本中,模式将略有不同,因为那时的隐式命名不同:case q"scala.this.Predef.any2ArrowAssoc[${_}]($foo).->[${_}]($bar)" =>
这里的另一个区别是需要在通配符周围使用花括号。2.10版本不支持字符串插入器中的$_
语法。