2010-12-18 12 views
13

के साथ मिलान स्केल पैटर्न मिलान मैंने पाया कि विकल्प (स्ट्रिंग्स के लिए) के साथ मिलान पैटर्न का उपयोग करते समय, स्कैला ऊपरी मामले (नीचे दिए गए उदाहरण में, MyValue1 और MyValue2) से शुरू होने वाले चर स्वीकार करता है, लेकिन कम मामले से शुरू नहीं होने वाले (myValue1, myValue2)। क्या यह एक बग या स्कैला की एक विशेषता है? मुझे यह संस्करण 2.8 में मिलता है। यदि यह एक विशेषता है, तो क्या कोई इसके पीछे तर्क को समझा सकता है?लोअरकेस वैरिएबल नाम

val myValue1 = "hello" 
val myValue2 = "world" 
val MyValue1 = "hello" 
val MyValue2 = "world" 

var x:String = "test" 

x match { 
    case MyValue1 | MyValue2 => println ("first match") 
    case myValue1 | myValue2 => println ("second match") 
} 

चल, मैं निम्नलिखित मिल:

scala> val myValue1 = "hello" 
myValue1: java.lang.String = hello 

scala> val myValue2 = "world" 
myValue2: java.lang.String = world 

scala> val MyValue1 = "hello" 
MyValue1: java.lang.String = hello 

scala> val MyValue2 = "world" 
MyValue2: java.lang.String = world 

scala> var x:String = "test" 
x: String = test 

scala> x match { 
| case MyValue1 | MyValue2 => println ("first match") 
| case myValue1 | myValue2 => println ("second match") 
| } 
<console>:11: error: illegal variable in pattern alternative 
    case myValue1 | myValue2 => println ("second match") 
     ^
<console>:11: error: illegal variable in pattern alternative 
    case myValue1 | myValue2 => println ("second match") 
        ^

संपादित: यह कोड मैं प्रयोग किया जाता है

तो यह वास्तव में एक सुविधा और नहीं एक बग है ... क्या कोई उपयोगी हो सकता है जब यह उपयोगी हो सकता है?

जब मैं का उपयोग करें:

x match { 
    case myValue1 => println ("match") 
    case _ => 
} 

मैं पिछले मामले पर एक unreachable code चेतावनी मिलती है, जिसका अर्थ है कि पहले एक हमेशा मेल खाता है।

+4

यह स्काला में आम प्रोग्रामिंग गलतियों में से एक है: http://stackoverflow.com/questions/1332574/common- प्रोग्रामिंग-गलतियों के लिए स्केला-डेवलपर्स करने वाली बचने/2489355 # 2489355। मैं पूरी तरह से उस धागे को पढ़ने की सलाह देता हूं - इसे इस तरह के अन्य गॉथस का गुच्छा मिला है। – Steve

+0

महान संदर्भ के लिए धन्यवाद। – Jus12

+0

एक उपयोगी उदाहरण: 'एक्स मैच {केस myValue1: स्ट्रिंग => println (" मैच: "+ myValue1); मामला _ =>} '-> myValue1 एक स्थानीय चर बन जाता है। – Madoc

उत्तर

33

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

तो, अपने उदाहरण लेखन के बराबर है:

x match { 
    case MyValue1 | MyValue2 => println ("first match") 
    case y | z => println ("second match") 
} 

आप बैकटिक का उपयोग करके यह काम कर सकते हैं:

x match { 
    case MyValue1 | MyValue2 => println ("first match") 
    case `myValue1` | `myValue2` => println ("second match") 
} 
+0

यह एक बहुत सूक्ष्म विशेषता है और कई लोग शायद यह सोचेंगे कि यह एक बग है। कामकाज देने के जवाब के रूप में चुना गया। – Jus12

5

यहाँ क्या हो रहा है कि myValue1 और myValue2 चर पहचानकर्ता (यानी, नए चर मूल्य मिलान किया जा रहा करने के लिए बाध्य कर रहे हैं की परिभाषा), जबकि MyValue1 और MyValue2 स्थिर पहचानकर्ता है कि मूल्यों की घोषणा का उल्लेख रूप में माना जाता के रूप में इलाज किया जा रहा है पहले। एक पैटर्न मैच मामले में, परिवर्तनीय पहचानकर्ताओं को निचले केस अक्षर से शुरू होना चाहिए, इसलिए पहला मामला सहजता से क्यों व्यवहार करता है। सटीक विवरण के लिए स्कैला भाषा विशिष्टता (http://www.scala-lang.org/docu/files/ScalaReference.pdf) की धारा 8.1 देखें।

अपने उदाहरण से थोड़ा फेरबदल, आप चर पहचानकर्ता देख सकते हैं:

scala> x match { 
| case MyValue1 | MyValue2 => println ("first match") 
| case myValue1 => println (myValue1) 
| } 
test 
+0

संदर्भ के लिए धन्यवाद। सटीक खंड 8.1.1 है। मैं केवल एक सही जवाब चुन सकता था। – Jus12

6

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

आप इसे का उदाहरण दिया भावना नहीं बना:

x match { 
    case myValue1 => println ("match") 
    case _ => 
} 

लेकिन भावना अगर हम चाहते हैं कि एक छोटे से बदल देखना आसान है:

x match { 
    case MyValue1 => println("match") 
    case MyValue2 => println("match") 
    case other => println("no match: "+other) 
} 
बेशक

, एक x बजाय इस्तेमाल कर सकते हैं other ऊपर, लेकिन यहां कुछ उदाहरण हैं जहां यह सुविधाजनक नहीं होगा:

(pattern findFirstIn text) { 
    // "group1" and "group2" have been extracted, so were not available before 
    case pattern(group1, group2) => 

    // "other" is the result of an expression, which you'd have to repeat otherwise 
    case other => 
} 

getAny match { 
    // Here "s" is a already a string, whereas "getAny" would have to be typecast 
    case s: String => 

    // Here "i" is a already an int, whereas "getAny" would have to be typecase 
    case i: Int => 
} 

ऐसे कई कारण हैं कि पहचानकर्ता के मिलान किए गए मान को असाइन करने के लिए पैटर्न मिलान के लिए यह सुविधाजनक क्यों है।

अब, हालांकि मुझे लगता है कि यह स्कैला के सबसे बड़े गलतफहमी में से एक है, क्योंकि यह इतना सूक्ष्म और अद्वितीय है, इसके पीछे तर्क यह है कि, अनुशंसित स्कैला शैली में, स्थिरांक ऊपरी भाग के साथ शुरू होने वाले ऊंट होते हैं, जबकि विधियों और vals और vars (जो वास्तव में भी तरीके हैं) ऊंट के साथ शुरू होता है ऊंट के अक्षरों से शुरू होता है। इसलिए स्थिरांक को स्वाभाविक रूप से शाब्दिक माना जाता है, जबकि अन्य को असाइन करने योग्य पहचानकर्ता माना जाता है (जो बाहरी संदर्भ में परिभाषित छाया पहचानकर्ता हो सकते हैं)।

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