有没有办法使用 scala-macros 获取给定构造函数的参数名称?
谢谢
请注意,:power
Paul Butcher 回答中的方法使您可以访问内部 API,如果您尝试在宏中执行此操作(或在 REPL 之外的运行时反射中,就此而言),这可能不是必需或不需要的。
因此,例如调用公共反射 API 中提供isConstructor
的普通旧文件是行不通的——你首先需要确保你有一个. 与. 您当然可以在非 REPL 代码中转换为内部 API,但这是危险且不必要的。以下是更好的解决方案:Symbol
members
MethodSymbol
tpe
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
宏中获得的方式完全相同。
我希望,这份 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)