1

我想对x -> yScala 宏中的操作树进行模式匹配。我正在针对 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?

4

1 回答 1

2

在一个完美的世界里,你肯定会期望第一个匹配,但这并不是那么简单。

每当您foo -> bar使用 Scala 编写代码时,您都会有效地调用类似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 不支持字符串插值器中的语法。

于 2014-07-14T09:19:38.227 回答