2011-09-01 14 views
13
में curried कंस्ट्रक्टर्स

वे पाते हैं कि अच्छी तरह से मिश्रण प्रतीत नहीं:प्रकरण कक्षाएं, पैटर्न मिलान और स्काला

abstract class A 
case class B (var a: Int)(var b: String) extends A 
case class C extends A 

निम्नलिखित कार्य नहीं करेगा:

B(1)("1") match { 
    case B(a)(b) => print("B") 
    case C() => print("C") 
} 

समस्या यह है कि पैटर्न मिलान है और करीबी तर्क काम नहीं कर रहे हैं। क्या इसके आसपास कोई कार्य है?

उत्तर

7

इसमें क्या गलत है?

def m(a: A) = a match { 
    case b: B => print("B") 
    case c: C => print("C") 
} 

मैं केवल इसलिए पूछ रहा हूं क्योंकि आपने इससे अधिक कार्यक्षमता नहीं मांगी है।

संपादित

यह मदद कर सकता है:

object Dog { 
    def apply(name: String)(size: Int) = new Dog(name)(size) 
    def unapply(dog: Dog) = Some(dog.name, dog.size) 
} 
class Dog(val name: String)(var size: Int) 

अब आप कुत्तों बना सकते हैं या तो इस तरह:

new Dog("Snoopy")(10) 

या इस तरह:

Dog("Snoopy")(10) 

लेकिन जब आप कुत्तों पर पैटर्न मिलान करते हैं तो कन्स्ट्रक्टर पैटर्न नहीं है। unapply(x$0: Q): Option[Int]:

Dog("Snoopy")(10) match { 
    case Dog(a, b) => // do sth with a or b 
} 
+0

आपका पहला उदाहरण काम करेगा, लेकिन मैं कुछ बदसूरत टाइपकास्टिंग किए बिना केस स्टेटमेंट में बीए और बीबी तक पहुंच नहीं पाएगा। साथ ही, आपके संपादन में, मुझे यकीन नहीं है कि मैं समझता हूं कि कन्स्ट्रक्टर पैटर्न क्यों नहीं है। क्या यह अनुपयोगी है? –

+0

ईमानदार होने के लिए मुझे नहीं पता कि यह क्यों काम करता है। मैं परीक्षण और त्रुटि के माध्यम से इसे ठोकर खाई। यह स्काला विनिर्देशन में कहीं निश्चित रूप से उल्लेख किया गया है। यदि आप अपने मामले में प्रासंगिक हैं तो आप इसे देखना चाहेंगे। – agilesteel

+1

हां, एक केस स्टेटमेंट में आपके द्वारा उपयोग किए जाने वाले पैटर्न को अनुपयुक्त फ़ंक्शन के परिणामस्वरूप दिया गया है। यह कभी नहीं किया जा सकता है। स्कैला विनिर्देश में संबंधित खंड §8.1.8 – Nicolas

2

आप एक सामान्य केस क्लास का उपयोग कर सकते हैं और एक से अधिक पैरामीटर सूची के साथ एक फैक्ट्री विधि को परिभाषित कर सकते हैं।

+0

क्या हम जोड़ सकते हैं कि फैक्ट्री विधि को 'लागू' नहीं किया जा सकता है अगर इसे साथी ऑब्जेक्ट में घोषित किया जाता है (क्योंकि इसमें वही मिटा होगा ई ने मामले वर्ग के लिए धन्यवाद घोषित किया)। – Nicolas

11

आप वर्ग बी के लिए बनाई गई unapply समारोह के हस्ताक्षर को देखें, तो आपको लगता है कि यह है देखेंगे। इस प्रकार, अनुपयुक्त फ़ंक्शन केस क्लास के पैरामीटर की पहली श्रेणी के साथ काम करता है।

यह स्केला विनिर्देश (§5.3.2) द्वारा की पुष्टि की है:

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

यह स्पष्ट रूप से दावा करता है कि एक्स्ट्रेक्टर के माध्यम से केवल पहला पैरामीटर अनुभाग उपलब्ध है।

कई समाधान:

  • अपने मानकों uncurry
  • एक पैटर्न गार्ड के साथ मिलान का उपयोग आप 2 मूल्यों का परीक्षण करना चाहते हैं: case [email protected](3) if x.b == "bazinga" => ...
  • एक सामान्य वर्ग का उपयोग करें और के साथ अपने स्वयं साथी वस्तु को परिभाषित अपने स्वयं लागू/अनुपयोगी
संबंधित मुद्दे