2012-12-11 6 views

Antwort

5

Beachten Sie, dass die :power Ansatz in Paul Butcher Antwort gibt Ihnen Zugriff auf interne APIs, die wahrscheinlich auch nicht notwendig ist, oder gewünscht, wenn Sie dies in einem Makro (oder in der Laufzeitreflexion außerhalb der REPL) tun wollen.

So zum Beispiel isConstructor auf einer einfachen alten Symbol von members im öffentlichen Reflection-API zur Verfügung gestellt Aufruf wird nicht funktionieren-Sie zuerst sicherstellen müssen, dass Sie ein MethodSymbol haben. Ähnlich mit tpe. Sie könnten natürlich die internen APIs in Nicht-REPL-Code umwandeln, aber das ist gefährlich und unnötig. Hier finden Sie eine bessere Lösung:

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)) 
} 

Oder einfach:

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

Beide geben Ihnen die folgenden:

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

nach Wunsch. Ich habe Laufzeit-Reflektion hier verwendet, um das Beispiel zu vereinfachen, aber das wird genau so funktionieren mit der Universe, die Sie von Ihrem Context in einem Makro erhalten.

+0

Ah - ein guter Punkt über: Power-Modus. Danke, dass du meine Erröten gerettet hast! –

1

Dieses REPL Transkript sollte, hoffe ich loslegen:

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) 
+0

Wie kann ich es in der Scala-Klasse in Kompilierzeit arbeiten lassen? –