5

scala-macros を使用して特定のコンストラクターのパラメーター名を取得する方法はありますか?

ありがとう

4

2 に答える 2

5

:powerPaul Butcher's answer のアプローチでは、内部 API にアクセスできることに注意してください。これは、マクロでこれを実行しようとしている場合 (または、REPL の外部の実行時リフレクションで実行しようとしている場合)、おそらく必要ないか、望ましくないでしょう。

したがって、たとえば、公開されている Reflection API で提供されisConstructorているプレーンな古いものを呼び出しても機能しません。最初に. 同様に。もちろん、非 REPL コードで内部 API にキャストすることもできますが、これは危険で不要です。以下はより良い解決策です。SymbolmembersMethodSymboltpe

import scala.reflect.runtime.universe._

class Foo(name: String, i: Int) { def this(name: String) = this(name, 0) }

typeOf[Foo].declaration(nme.CONSTRUCTOR).asTerm.alternatives.collect {
  case m: MethodSymbol => m.paramss.map(_.map(_.name))
}

あるいは単に:

typeOf[Foo].declarations.collect {
  case m: MethodSymbol if m.isConstructor => m.paramss.map(_.map(_.name))
}

これらは両方とも、次のことを示します。

List(List(List(name, i)), List(List(name)))

望んだ通りに。ここでは例を単純化するためにランタイム リフレクションを使用しましたが、これはマクロでUniverse取得したものとまったく同じように機能します。Context

于 2012-12-11T12:59:10.283 に答える
1

この REPL トランスクリプトは、あなたを動かしてくれるはずです。

Welcome to Scala version 2.10.0-RC5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_09).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'.          **
** scala.tools.nsc._ has been imported      **
** global._, definitions._ also imported    **
** Try  :help, :vals, power.<tab>           **

scala> class Foo(x: Int, y: Float)
defined class Foo

scala> (typeOf[Foo].members find (_.isConstructor)).get.tpe.params map (_.name)
res1: List[$r.intp.global.Symbol#NameType] = List(x, y)
于 2012-12-11T10:10:54.777 に答える