स्काला मल्टीपल टाइप पैटर्न मैचिंग


80

मैं सोच रहा हूं कि मैं कई प्रकार के पैटर्न मिलान का उपयोग कैसे कर सकता हूं। मेरे पास है:

abstract class MyAbstract

case class MyFirst extends MyAbstract
case class MySecond extends MyAbstract
case class MyThird extends MyAbstract // shouldn't be matched and shouldn't call doSomething()

val x: MyAbstract = MyFirst

x match { 
 case a: MyFirst => doSomething()
 case b: MySecond => doSomething()
 case _ => doSomethingElse()
}

इसलिए मैं कुछ लिखना चाहूंगा:

x match {
 case a @ (MyFirst | MySecond) => doSomething()
 case _ => doSomethingElse()
}

मैंने कुछ ट्यूटोरियल में समान निर्माण देखा, लेकिन यह मुझे त्रुटि देता है:

pattern type is incompatible with expected type;
[error]  found   : object MyFirst
[error]  required: MyAbstract

तो क्या मामले के खंड में कुछ अलग-अलग प्रकारों को परिभाषित करने का एक तरीका है? मुझे लगता है कि यह कोड को सुंदर बना देगा। जैसे कि मेरे पास उनमें से 5 होंगे, मैं एक ही कोड को 5 बार (doSomething () कॉलिंग) लिखूंगा।

अग्रिम में धन्यवाद!


मुझे लगता है कि यह एक XY- समस्या है; आपके पास सभी doSomethingमामलों के लिए एक सामान्य सुपरक्लास है , case a : MyAbstractतो तत्कालीन मेल क्यों नहीं ...?
पैट्रिक iewiek

क्षमा करें, यह उल्लेख करना भूल गया कि मेरे पास अन्य कक्षाएं हैं, जो MyAbstract वर्ग का विस्तार करती हैं और doSomething को कॉल नहीं करना चाहिए।
Psisoyev

ओह, ठीक है, बस यह स्पष्ट करना चाहता था कि :) आपके पास अब आपकी समस्या का एक सही उत्तर है।
पेट्रीक kwiek

जवाबों:


135

आप अपनी केस कक्षाओं के लिए कोष्ठक को याद कर रहे हैं। पैरामीटर सूचियों के बिना केस की कक्षाओं को पदावनत किया जाता है।

इसे इस्तेमाल करे:

abstract class MyAbstract
case class MyFirst() extends MyAbstract
case class MySecond() extends MyAbstract

val x: MyAbstract = MyFirst()


x match {
   case aOrB @ (MyFirst() | MySecond()) => doSomething(aOrB)
   case _ => doSomethingElse()
}

यदि आपके पास अपने केस क्लासेस के लिए बहुत सारे परमेस हैं और लंबे Foo(_,_,..)पैटर्न लिखना पसंद नहीं करते हैं , तो हो सकता है:

x match {
   case aOrB @ (_:MyFirst | _:MySecond) => doSomething(aOrB)
   case _ => doSomethingElse()
}

या केवल:

x match {
   case _:MyFirst | _:MySecond => doSomething(x) // just use x instead of aOrB
   case _ => doSomethingElse(x)
}

लेकिन शायद आप सिर्फ सिंगलटन केस ऑब्जेक्ट्स चाहते थे?

abstract class MyAbstract
case object MyFirst extends MyAbstract
case object MySecond extends MyAbstract

val x: MyAbstract = MyFirst

x match {
   case aOrB @ (MyFirst | MySecond) => doSomething()
   case _ => doSomethingElse()
}

1
और कोष्ठक से बचने का कोई उपाय नहीं है? जैसा कि मेरे पास कुछ पैरामीटर हैं और यह बदसूरत हो जाता है: मामला a @ (MyFirst ( , _, _, _, _) | MySecond ( , _, _, _, _)) => doSomething ()
psisemev

9
क्या आपको याद आया obj @ (_: MyFirst | _: MySecond)?
जीन-फिलिप पेलेट

मुझे objऐसे मामलों की आवश्यकता है, जहां मैं इसे doSomethingकॉल में उपयोग कर रहा हूं । मेरे मामले में, कॉल का doSomethingउपयोग नहीं किया गया था obj, इसलिए मुझे इसकी आवश्यकता नहीं है। लेकिन वैसे भी, आपकी टिप्पणी के लिए धन्यवाद!
Psisoyev

@ जीन-फिलिप्पेलेट वास्तव में मेरे पास है। मुझे इसे जोड़ने के लिए अपनी पोस्ट को संपादित करने दें।
फैज

1
यह अच्छा होगा यदि संकलित इनपुट प्रकार को डिफ़ॉल्ट करने के बजाय निकटतम सामान्य प्रकार खोजने के लिए पर्याप्त स्मार्ट था।
nilskp
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.