2012-08-16 27 views
17

मैं निम्नलिखित वर्ग पदानुक्रम की एक टपल पैटर्न मिलान:स्काला - संबंधित प्रकार

class A 
class B extends A 
class C extends A 

तो, वहाँ एक और वर्ग है जो इन कक्षाओं के उदाहरण ले जाता है और वहाँ एक विधि है, जिसमें से दो मामलों पैटर्न मिलान इस तरह संभव हो रहे हैं:

class D (one: A, two: A) { 

    def work { 
    (one, two) match { 
     case (o, t): (B, B) => ... blablabla 
     case (o, t): (B, C) => ... blablabla 
     case _ => 
    } 
    } 
} 

हालांकि, जब यह दूसरा मामला (B, C) के पक्ष में मिलान समाधान हो जाना चाहिए, यह इसके (B, B) के रूप में हल करने और वर्ग डाली अपवाद है कि C cannot be cast to B साथ आता है की कोशिश करता है। क्यूं कर? क्या करें? मैं इसके आसपास कैसे आ सकता हूं?

उत्तर

26

आपका वाक्यविन्यास बिल्कुल सही नहीं है (संकलित नहीं करता है)।

यह हालांकि काम करता है:

object Matcher extends App { 

    class A 
    class B extends A 
    class C extends A 

    class D(one: A, two: A) { 

    def work { 
     (one, two) match { 
     case (o: B, t: B) => println("B") 
     case (o: B, t: C) => println("C") 
     case _ => 
     } 
    } 
    } 

    val d1 = new D(new B, new B) 
    val d2 = new D(new B, new C) 

    d1.work 
    //B 
    d2.work 
    //C 
} 
+0

मैं सही वाक्यविन्यास को समझने के लिए इतनी देर तक संघर्ष कर रहा हूं ... धन्यवाद! – Benoit

2

मैंने यह कोड काम किया है।
सबसे पहले मैंने आपकी कक्षा परिभाषा में एक मामला जोड़ा।

case class A 
case class B extends A 
case class C extends A 

दूसरी बार मैंने work बदल दिया।

class D(one: A, two: A) { 
    def work { 
    (one, two) match { 
     case (o: B, t: B) => println("BB") 
     case (o: B, t: C) => println("BC") 
     case (o: C, t: C) => println("CC") 
     case _ => println("AA") 
    } 
    } 
} 

मैं अब क्या हो गया है:

new D(B(),B()).work  => BB 
new D(B(),C()).work  => BC 
new D(C(),C()).work  => CC 
new D(A(),B()).work  => AA 

case एक लागू कहते हैं और एक unapply विधि।

+0

हाँ, केस कक्षाएं ... लेकिन उनके पास विरासत के साथ कीड़े हैं .. अगर वे इसे कभी ठीक करते हैं तो मैं बहुत खुश हूं ... – noncom

+0

मैं पूरी तरह से आपके साथ हूं। –

+1

यह कोड आधुनिक स्कैला में संकलित नहीं होगा, क्योंकि 2.9 के बाद से केस विरासत प्रतिबंधित है। @noncom यह एक बग नहीं है, यह डिजाइन –

7

समस्या, हमेशा की तरह, प्रकार के मिटा दिया जाता है। (B,C)Tuple2[B,C] के लिए वाक्य रचनात्मक चीनी है, जो रनटाइम पर Tuple2 को मिटा दिया गया है। केस स्टेटमेंट सत्यापित करता है कि (B,C)Tuple2 से मेल खाता है, लेकिन फिर इसे कास्ट करने में विफल रहता है।

आपके मामले में, सबसे आसान समाधान नहीं बल्कि उन्हें एक टपल में लपेटकर से, व्यक्तिगत रूप से 'एक' और 'दो' के खिलाफ मैच के लिए होगा:

one match { 
    case o : B => two match { 
    case p : C => ... 
    case p : B => ... 
    } 
    ... 
} 

यह है, तो सुंदर नहीं है लेकिन ऐसा नहीं होगा एक ही समस्या से पीड़ित हैं।

संपादित करें: वास्तव में, मैं ब्रायन स्मिथ के समाधान के साथ जाऊंगा - बाहर की बजाय टुपल के अंदर मिलान करना। यह समस्या को इसी तरह से टालता है, लेकिन अच्छा लगता है।