2012-12-11 17 views

Odpowiedz

5

Należy zauważyć, że podejście :power w odpowiedzi Paul Butcher daje Ci dostęp do API wewnętrznych, co chyba nie jest ani konieczne, lub pożądane, jeśli próbujesz to zrobić w makrze (lub w środowisku wykonawczym odbicie poza REPL, o to chodzi).

Tak na przykład dzwoniąc isConstructor na zwykłym starym Symbol dostarczonych przez members w publicznym Reflection API nie będzie działać, trzeba najpierw upewnić się, że masz MethodSymbol. Podobnie z tpe. Można oczywiście rzutować na wewnętrzne API w kodzie innym niż REPL, ale jest to niebezpieczne i niepotrzebne. Poniżej znajduje się lepszym rozwiązaniem:

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

Lub po prostu:

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

Oba daje następujące:

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

zgodnie z zapotrzebowaniem. Użyłem tutaj refleksji runtime, aby uprościć przykład, ale to będzie działać dokładnie tak samo z Universe, które otrzymasz ze swojego Context w makrze.

+0

Ah - dobry punkt dotyczący: trybu zasilania. Dzięki za uratowanie moich rumieńców! –

1

Ten REPL zapis powinien być ci, mam nadzieję:

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

Jak mogę sprawić, aby działał w klasie scala podczas kompilacji? –