1

Scala では、次の変数引数でパターン マッチングが可能ですunapplySeq

case class A(args: String*)

A("a", "b", "c") match {
  case A(args @ _*) => args  // Seq("a", "b", "c")
}

マクロでそのようなパターンを生成したい。どうすればいいですか?当然のことですが、うまくいきません。

scala> pq"x @ _*"
<console>:11: error: illegal start of simple pattern
              pq"x @ _*"
                       ^

ただし、パターンから実際の型を抽出し、それを使用qしてパターンを再作成することは可能です。

scala> val q"??? match { case Hello($ident @ $thingy) => }" = q"??? match { case Hello(any @ _*) => }"
ident: reflect.runtime.universe.Name = any
thingy: reflect.runtime.universe.Tree = (_)*

scala> pq"$ident @ $thingy"
res1: reflect.runtime.universe.Bind = (any @ (_)*)

しかし、これはハックすぎるので、やりたくありません。

4

2 に答える 2

1

準引用符がサポートされていない理由pq"x @ _*"は、パターン構文の定義方法にあります。言語の文法は、Pattern生産規則を通じてパターン構文を定義します。ご覧のとおり_*、それ自体は実際には有効なパターンではありませんPatterns。エクストラクタ内で一連のパターンをモデル化するために使用される特別なプロダクション ルール内でのみ機能します。

準引用符を使用すると、さまざまなインターポレーターを介して文法のさまざまなコンテキストにプラグインできます。残念ながら、可能なすべてのコンテキストをサポートすることはできません。API に何百ものインターポレーターが必要になるからです。

最も簡単な解決策は、実際にStar(Ident(termNames.WILDCARD))ここで使用することです。

于 2015-02-20T12:26:48.123 に答える