2012-06-27 15 views
11
sealed class A 
class B1 extends A  
class B2 extends A 

मान लिया जाये कि हम वर्ग A की वस्तुओं की एक सूची है: वैल एल: सूची [एक] = सूची (नई बी 1, बी 2 नई, नई बी 1, नई बी 1)isInstanceOf का उपयोग कब करें और मैच-केस-स्टेटमेंट (स्कैला में) का उपयोग कब करें?

और हम बाहर फ़िल्टर करना चाहते हैं प्रकार बी 1 के तत्व। फिर हम एक विधेय की जरूरत है और दिए गए दो विकल्पों का उपयोग कर सकते:

l.filter(_.isInstanceOf[B1]) 

या

l.filter(_ match {case b: B1 => true; case _ => false}) 

व्यक्तिगत रूप से, मैं पहली बार दृष्टिकोण अधिक पसंद है, लेकिन मैं अक्सर पढ़ते हैं, एक match-case बयान अधिक का उपयोग करना चाहिए अक्सर (उन कारणों से जिन्हें मैं नहीं जानता)।

इसलिए, सवाल यह है: match-case कथन के बजाय isInstanceOf का उपयोग करने में कमी है? किसी को किस दृष्टिकोण का उपयोग करना चाहिए (और यहां किस दृष्टिकोण का उपयोग किया जाना चाहिए और क्यों)?

उत्तर

17

आप ऐसे ही फ़िल्टर कर सकते हैं:

l.collect{ case x: B1 => x } 

और अधिक पठनीय है यही कारण है, IMO।

+3

और आपको अंत में संक्षिप्त प्रकार ('सूची [बी 1] ') देता है। –

+0

बहुत अधिक पठनीय लगता है, धन्यवाद।लेकिन इस कथन में डिफ़ॉल्ट मामला क्या होगा? इस शॉर्टकट केस स्टेटमेंट और इसका उपयोग कैसे किया जाता है, इसके बारे में मैं और अधिक पृष्ठभूमि जानकारी कहां पढ़ सकता हूं? –

+0

@ जॉन थ्रीपवुड [इस पोस्ट] पर एक नज़र डालें (http://ochafik.com/blog/?p=393)। यह सबसे अच्छा नहीं है, लेकिन अभी भी बहुत अच्छा "संग्रह का कारण" है। संक्षेप में, संग्रह नक्शा की तरह है, लेकिन केवल उन मानों के लिए एक कार्य करें जो * (आंशिक) * फ़ंक्शन के लिए परिभाषित किया गया है जिसे आप इस विधि में पास करते हैं। इस मामले में मिलान करने वाला स्कैला का पैटर्न [आंशिक फ़ंक्शन] (http://stackoverflow.com/questions/5668053/scala-partial-functions) के शीर्ष पर किया जाता है। इसके अलावा, आपको घुंघराले ब्रैकेट का उपयोग करने की आवश्यकता है। –

7

कोई अंतर नहीं हैं

बिल्ली t.scala:

class A { 
    def x(o: AnyRef) = o.isInstanceOf[A] 
    def y(o: AnyRef) = o match { 
    case s: A => true 
    case _ => false 
    } 
} 

$ scalac प्रिंट t.scala

[[syntax trees at end of cleanup]]// Scala source: t.scala 
package <empty> { 
    class A extends java.lang.Object with ScalaObject { 
    def x(o: java.lang.Object): Boolean = o.$isInstanceOf[A](); 
    def y(o: java.lang.Object): Boolean = { 
     <synthetic> val temp1: java.lang.Object = o; 
     temp1.$isInstanceOf[A]() 
    }; 
    def this(): A = { 
     A.super.this(); 
    () 
    } 
    } 
} 
+0

ग्रेट, पृष्ठभूमि जानकारी के लिए धन्यवाद, स्कैला कंपाइलर क्या करेगा। –

9

match-case का लाभ यह है कि तुम नहीं है यदि आप उस पर संचालन करना चाहते हैं तो ऑब्जेक्ट को डालना होगा जो इसके संक्षिप्त प्रकार पर निर्भर करता है।

if (obj.isInstanceOf[A]) println(obj) 

हालांकि, अगर आप निम्न करें::

if (obj.isInstanceOf[A]) { 
    val a = obj.asInstanceOf[A] 
    println(a.someField) // someField is declared by A 
} 

तो मैं

निम्नलिखित स्निपेट में isInstanceOf का उपयोग कर जब से तुम इस तरह के एक आपरेशन प्रदर्शन नहीं करते ठीक हो रहा है डी match-case का उपयोग करने के पक्ष में हो:

obj match { 
    case a: A => println(a.someField) 
    case _ => 
} 

यह थोड़ा परेशान है ing आप "अन्यथा" -case शामिल करने के लिए है, लेकिन collect का उपयोग कर (के रूप में ओम-nom-nom द्वारा की ओर संकेत किया) मदद कर सकता है, कम से कम अगर आप संग्रह के साथ काम Seq से विरासत:

collectionOfObj.collect{ case a: A => a}.foreach(println(_.someField)) 
+0

आपके अच्छे उदाहरणों के लिए धन्यवाद, बहुत अच्छा। –

9

कोई है isInstanceOf का उपयोग कर समस्या, जब तक आप asInstanceOf का उपयोग नहीं करते हैं।

कोड जो दोनों का उपयोग करता है वह भंगुर है, क्योंकि जांच और कास्टिंग अलग-अलग क्रियाएं होती हैं, जबकि मिलान का उपयोग करके आपके पास एक ही क्रिया होती है।

+0

संकेत के लिए धन्यवाद, मैं इसके लिए बाहर देखूँगा। –

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