2013-04-18 26 views

cevap

39

MethodSymbol içine pompalamak için plan saha yöntemleri

def getMethods[T:TypeTag](t:T) = typeOf[T].members.collect { 
    case m:MethodSymbol => m 
    } 

çekin gelmez aşağıda kullanarak Örneğin , hassas bunu sağlayan bir isCaseAccessor yöntemi vardır:

:
def getMethods[T: TypeTag] = typeOf[T].members.collect { 
    case m: MethodSymbol if m.isCaseAccessor => m 
}.toList 

Şimdi aşağıdaki yazabilirsiniz 10

scala> case class Person(name: String, age: Int) 
defined class Person 

scala> getMethods[Person] 
res1: List[reflect.runtime.universe.MethodSymbol] = List(value age, value name) 

Ve yalnızca istediğiniz yöntem sembollerini alırsınız.

+0

Ah, şimdi yaklaşımımın yanlış olduğunu anlıyorum. Bilinmeyen bir vaka sınıfından davaya nasıl geçilir? Şu anda valde kayıtlı olan IE One: Herhangi bir –

+0

Bekleyin, yok currentMirror.reflect (someCaseClass) .symbol.asType.typeSignature.members –

+0

Bu, scala 2.10 altında çok iş parçacıklı ortamlarla çalışabilir mi? – jilen

10

Eğer meraklı olmak istiyorsanız, kurucu sembolünü inceleyerek sırayla alabilirsiniz. Bu kod, söz konusu vaka sınıfı türü tanımlanmış birden fazla kurucuya sahip olsa bile çalışır.

import scala.collection.immutable.ListMap 
    import scala.reflect.runtime.universe._ 

    /** 
    * Returns a map from formal parameter names to types, containing one 
    * mapping for each constructor argument. The resulting map (a ListMap) 
    * preserves the order of the primary constructor's parameter list. 
    */ 
    def caseClassParamsOf[T: TypeTag]: ListMap[String, Type] = { 
    val tpe = typeOf[T] 
    val constructorSymbol = tpe.decl(termNames.CONSTRUCTOR) 
    val defaultConstructor = 
     if (constructorSymbol.isMethod) constructorSymbol.asMethod 
     else { 
     val ctors = constructorSymbol.asTerm.alternatives 
     ctors.map(_.asMethod).find(_.isPrimaryConstructor).get 
     } 

    ListMap[String, Type]() ++ defaultConstructor.paramLists.reduceLeft(_ ++ _).map { 
     sym => sym.name.toString -> tpe.member(sym.name).asMethod.returnType 
    } 
    } 
+0

Bu durumun scala.ScalaReflectionException ile başarısız olduğu durumları buluyorum: 'constructorSymbol.asTerm.alternatives' ifadesinde bir terim değil. "Bildirge" için dokümantasyon yorumu, "Aşırı YüklüSembol" anlamına gelir, ancak böyle bir varlık mevcut değildir. –

+0

Bunun gerçekleştiği ortaya çıkıyor çünkü 'bu.type' sözcüğünü, söz konusu vaka sınıfının bir üst türü olarak kullanılan bir özellikten çağırıyordum. –

+0

Ayrıca, 'case sınıfı P (i: Int) (j: Int) '. –