2011-09-17 11 views
9

PHP introduces a method that allows you to pick out all public values of an instance. में एक इंस्टेंस के सार्वजनिक फ़ील्ड (और उनके संबंधित मान) प्राप्त करना स्कैला में ऐसा करने का कोई तरीका है? यह एक तत्काल वर्ग (ऑब्जेक्ट नहीं) के सभी सार्वजनिक क्षेत्रों के सभी मूल्यों को लाने के लिए है।स्कैला/जावा

आइए आइए हम मान लेते मैं इस वर्ग

class TestElement(datatype: Datatype, var subject: String, var day: Int, var time: Int) 
    extends DataElement(datatype: Datatype) {  
    def to(group: Group) = group.add(this); 
} 

var element = new TestElement(datatype, "subject", 1, 1); 

क्या मैं प्रश्न में विधि से की जरूरत है, एक नक्शे या मूल्यों के दो संग्रह प्राप्त करने के लिए है।

var element.method          // the function I need 
ret: (("subject", "subject"), ("day", 1), ("time", 1)) // its output 

उत्तर

20

यह सोने का समय है, तो मैं एक पूर्ण जवाब के लिए समय नहीं है, लेकिन (निजी क्षेत्रों के लिए या getDeclaredFields) element.getClass.getFields के परिणामों को देखने - आप उनके मूल्यों को लाने के लिए Field वस्तुओं पर getValue(element) कॉल कर सकते हैं।


जाग अब, और अभी भी कोई बेहतर जवाब है, तो:

सबसे पहले, ध्यान दें कि जावा मामले में, अपने वर्ग के लिए एक सार्वजनिक क्षेत्र विषय नहीं है क्या यह है एक निजी क्षेत्र के अधीन है और एक्सेसर विधियों विषय() और subject_ $ eq (स्ट्रिंग)।

आप जैसा कि ऊपर वर्णित जोड़े से एक मानचित्र पॉप्युलेट निजी क्षेत्र की वस्तुओं से अधिक पुनरावृति कर सकते हैं:

def getFields(o: Any): Map[String, Any] = { 
    val fieldsAsPairs = for (field <- o.getClass.getDeclaredFields) yield { 
    field.setAccessible(true) 
    (field.getName, field.get(o)) 
    } 
    Map(fieldsAsPairs :_*) 
} 

अब आप या तो TestElement पर इस विधि को परिभाषित कर सकते (this साथ o की जगह), या अधिक आम तौर पर उपयोगी ताकि आप किसी भी संदर्भ पर getFields कॉल कर सकते हैं

implicit def any2FieldValues[A](o: A) = new AnyRef { 
    def fieldValues = getFields(o) 
} 

तो किसी रूपांतरण से परिभाषित

element.fieldValues 

आपको इच्छित परिणाम देगा।

+0

उत्कृष्ट, बहुत बहुत धन्यवाद – sdkfasldf

+0

'_ _' वाक्यविन्यास क्या करता है? –

2

आप मामले कक्षाओं के लिए कुछ अपेक्षाकृत इस के पास कर सकते हैं:

case class SomeEntity(name : String, value : Int, misc : Boolean) 
val s = SomeEntity("Tom", 42, false) 
println(s.productIterator.map(_.toString).mkString(", ")) // "Tom, 42, false" 

... के रूप में आप, उम्मीद करेंगे प्रकार किसी भी के तत्वों से अधिक productIterator दोहराता। यह विधि केवल केस कक्षाओं के लिए स्वचालित रूप से जेनरेट की जाती है, और आप फ़ील्ड का नाम पुनर्प्राप्त नहीं करेंगे। कुछ और के लिए, आपको प्रतिबिंब का उपयोग करने की आवश्यकता होगी, और इसके लिए, आप बाहर आने के लिए 2.10 का इंतजार करना चाहेंगे।

+0

2.10 में क्या परिवर्तन? – sdkfasldf

3

फिलिप के उत्तर प्रति एक, आप कक्षाओं के मामले में ऐसा कर सकते हैं।

अधिक विस्तृत रूप हालांकि, उसी तकनीक का Product की किसी भी उपवर्ग के लिए काम करता है। साथ ही केस क्लास, टुपल्स एक और स्पष्ट उदाहरण हैं, लेकिन सूची उससे कहीं अधिक व्यापक है।

के बजाय एक लौटने: जो @duncan बनाने के दृष्टिकोण प्रकार- मजबूत करके इस सुधार करने के लिए प्रयास करने के लिए http://www.scala-lang.org/api/current/scala/Product.html

1

बस एक ध्यान दें:

"ज्ञात उपवर्गों" पर एक नज़र डालें, यहाँ Map[String, Any], जहां मूल्य किसी भी रूप में लिखा गया हो, तो आपको निम्न कर सकता है:

def propertiesAsPairs() = { 
    val fields = (this.getClass.getDeclaredFields()) 
    for (field <- fields) yield { 
     field.setAccessible(true); 
     (field.getName, field.get(this)); 
    } 
} 
+0

इसका रिटर्न प्रकार क्या है? यह मुझे ऐरे की तरह दिखता है [जोड़ी [स्ट्रिंग, कोई भी]], जिसने आपको कुछ भी नहीं खरीदा है? –

0

स्काला जानबूझ बनाता val, var और def शेयर एक आम इंटरफेस है, तो आप कर सकते हैं repl किसी भी कोड को तोड़ने के बाद उत्तरार्द्ध के साथ पूर्व दो - एक recompile की आवश्यकता के बिना भी।

तो, जब आप जो चाहते हैं वह करना संभव है, तो इसका परिणाम भंगुर कोड होगा, जो इस तरह की चीज नहीं करता है।

+0

मुझे लगता है कि मैं तर्क दूंगा कि इस तरह के डेटा वर्गों के लिए, बिंदु सिर्फ फ़ील्ड में मूल्यों को बंद कर रहा है। –

+0

हालांकि आपने मुझे http://stackoverflow.com/q/7477248/97777 पूछने के लिए कहा है –

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

  • कोई संबंधित समस्या नहीं^_^