2011-05-27 17 views
18

इस वर्ग पर विचार करें:एकाधिक तर्क सूचियों वाले वर्ग से पैटर्न कैसे मिलान करें?

class DateTime(year: Int, month: Int, day: Int)(hour: Int, minute: Int, second: Int) 

unapply विधि कैसा दिखता है, अगर मैं कुछ के खिलाफ मिलान करना चाहता हूं:

dt match { 
    case DateTime(2012, 12, 12)(12, _, _) => // December 12th 2012, 12 o'clock 
    /* ... */ 
} 

मैंने यह कोशिश की:

def unapply(dt: DateTime) = 
    Some((dt.year, dt.month, dt.day),(dt.hour, dt.minute, dt.second)) 

लेकिन वह वास्तव में काम नहीं किया था।

उत्तर

21

प्रकरण कक्षाएं मिलान (और उनके अन्य गंधा बातें करते हैं) केवल मानकों का पहला सेट पर:

scala> case class A(i: Int)(j: Int) { } 
defined class A 

scala> A(5)(4) match { case A(5) => "Hi" } 
res14: java.lang.String = Hi 

scala> A(5)(4) == A(5)(9) 
res15: Boolean = true 

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

आप विभाजन के कुछ प्रकार से मेल खाते हैं और सब कुछ पर समानता है, लेकिन करने के लिए सक्षम किया जा रहा सहित गंधा मामले श्रेणी की सुविधाओं का उपयोग करना चाहते हैं, तो आप कर सकते थे घोंसला मामले कक्षाएं:

case class Time(hour: Int, minute: Int, second: Int) { } 
case class Date(year: Int, month: Int, day: Int) { } 
case class DateTime(date: Date, time: Time) { } 

scala> val dt = DateTime(Date(2011,5,27), Time(15,21,50)) 
scala> dt match { case DateTime(Date(2011,_,_),Time(h,m,50)) => println(h + ":" + m) } 
15:21 
1

यह शायद नहीं था काम क्योंकि स्कैला के पास कोई अल्पविराम ऑपरेटर नहीं है, और आप एक्स्ट्रेक्टर से Some((a,b),(x,y)) लौट रहे हैं। आप Some(((a,b,c),(x,y,z))) बजाय का उपयोग किया है (यानी एक Tuple2[Tuple3[A,B,C],Tuple3[X,Y,Z]] मुझे लगता है कि यह शायद काम करेगा।

9
बस रेक्स के जवाब पर बनाने के लिए

, न केवल आप कर सकते हैं पहले पैरामीटर खंड पर केवल पैटर्न मैच है, लेकिन इस व्यवहार डिज़ाइन द्वारा बहुत ज्यादा है।

अधिक दिलचस्प सवाल क्यों मामले कक्षाएं, बीजीय डेटा प्रकार के रूप में, यहां तक ​​कि कई पैरामीटर सूची का समर्थन है ...

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

+3

एकाधिक पैरामीटर सूचियां अच्छी हैं क्योंकि आपके पास एकाधिक var args सूचियां हो सकती हैं। –

+0

शायद यह थोड़ा सा उदाहरण है, लेकिन यदि आप 'केस क्लास माईकेज़ [ए <: विथबार] (ए: ए) (बी: ए # बार)' कह सकते हैं और बॉक्स के बाहर सभी "निफ्टी फीचर्स" प्राप्त कर सकते हैं, तो यह 'एएल' के लिए एनोटेशन के बिना 'वैल एक्स = माईकेस (फूविथबार (...)) (बार (...))' जैसे नए उदाहरण बनाना संभव होगा। 'माईकेस [ए <: विदबार] (ए: ए, बी: ए # बार) जैसे हस्ताक्षर के साथ, आपको' वैल एक्स = माईकेज़ [फूविथबार] (फूविथबार (...), बार (..) के साथ तत्काल होना होगा। ।)) ', क्योंकि टाइप एफरेंस' ए # बार 'के पैरामीटर के रूप में उसी पैरामीटर सूची में निर्दिष्ट होने पर' ए # बार 'के लिए काम नहीं करेगा। – falconepl

+0

केस क्लास प्रलोभन से बचने का एक अन्य कारण। वे भाषा की कई उन्नत विशेषताओं (या अवधारणाओं) के साथ अच्छी तरह से खेल नहीं पाते हैं। – matanster

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