2013-04-18 7 views
25

से फ़ील्ड मानों को कैसे निकालूं I ​​scala 2.10 में नए प्रतिबिंब मॉडल का उपयोग करके स्केल में केस क्लास से फ़ील्ड मान कैसे निकाल सकता हूं? उदाहरण के लिए, नीचे का उपयोग कर बाहर खींच नहीं करता है क्षेत्र विधियोंस्कैला 2.10 प्रतिबिंब, मैं केस क्लास

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

मैं उन्हें

for {field <- fields} { 
    currentMirror.reflect(caseClass).reflectField(field).get 
    } 

उत्तर

39

MethodSymbol में पंप करने के लिए योजना बना रहे हैं एक isCaseAccessor विधि है कि आप ठीक ऐसा करने के लिए अनुमति देता है:

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

अब आप निम्न लिख सकते हैं:

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) 

और आपको केवल वही विधि प्रतीक मिलते हैं जिन्हें आप चाहते हैं।

+0

आह मुझे पता है कि मेरा दृष्टिकोण गलत था। किसी अज्ञात केस क्लास से केस प्राप्त करने के लिए कोई विचार कैसे? आईई एक जो वर्तमान में वैल के रूप में संग्रहीत है कुछ कैस क्लास: कोई भी –

+0

रुको, इसे वर्तमान मिरर.फ्रैक्ट (कुछ कैस क्लास) .symbol.asType.typeSignature.members –

+0

क्या यह स्केल 2.10 के तहत बहु-थ्रेड वातावरण के साथ काम कर सकता है? – jilen

10

यदि आप प्रशंसक प्राप्त करना चाहते हैं तो आप उन्हें रचनाकार प्रतीक का निरीक्षण करके प्राप्त कर सकते हैं। यह कोड तब भी काम करता है जब केस क्लास प्रकार के प्रश्न में कई रचनाकार परिभाषित होते हैं।

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

मुझे ऐसे मामले मिल रहे हैं जहां यह 'scala.ScalaReflectionException: अभिव्यक्ति' creatorSymbol.asTerm.alternatives 'अभिव्यक्ति में एक शब्द नहीं है। 'घोषणा' के लिए प्रलेखन टिप्पणी 'ओवरलोडेड सिंबल' को संदर्भित करती है, लेकिन ऐसी कोई इकाई मौजूद नहीं है। –

+0

यह पता चला है कि यह हो रहा था क्योंकि कारण मैं मामले में वर्ग वर्ग के सुपरटेप के रूप में उपयोग की जाने वाली विशेषता से 'this.type' के साथ इसे बुला रहा था। –

+0

इसके अलावा, 'केस क्लास पी (आई: इंट) (जे: इंट) '। –

संबंधित मुद्दे