2010-04-28 12 views
15

जब Vals में tuples खोलने की कोशिश कर रहा स्केला में निम्नलिखित व्यवहार देखा है:स्काला के टपल unwrapping अति सूक्ष्म अंतर

scala> val (A, B, C) = (1, 2, 3) 
<console>:5: error: not found: value A 
     val (A, B, C) = (1, 2, 3) 
      ^
<console>:5: error: not found: value B 
     val (A, B, C) = (1, 2, 3) 
      ^
<console>:5: error: not found: value C 
     val (A, B, C) = (1, 2, 3) 
       ^

scala> val (u, v, w) = (1, 2, 3) 
u: Int = 1 
v: Int = 2 
w: Int = 3 

कि राजधानियों के साथ शुरू क्योंकि स्केला का पैटर्न मिलान तंत्र स्वचालित रूप से मान लिया जाता है कि सभी पहचानकर्ता पैटर्न भीतर स्थिरांक हैं है , या यह किसी अन्य कारण के कारण है?

धन्यवाद!

उत्तर

20

हाँ, और यह खराब हो जाता है:

val (i, j) : (Int, Int) = "Hello" -> "World" 

ऊपर संकलन और एक ClassCastException साथ कार्यावधि में असफल हो जायेगी। यह भूलना आसान है कि (i, j) घोषणा पैटर्न है।

संपादित: ziggystar के लिए, स्काला काम नियम कहते हैं कि बयान में:

val p = expr //or var 

p या तो एक पहचानकर्ता या एक पैटर्न हो सकता है (स्काला में खंड 15.7 की प्रोग्रामिंग देखना, पीपी 284)। उदाहरण के लिए, निम्नलिखित मान्य है:

val x :: y :: z :: rest = List(1, 2, 3, 4) 

तथ्य यह है कि पैटर्न मिट (यानी पैरामीट्रिक प्रकार की जानकारी अनियंत्रित है) का अर्थ है कि अपने मूल उदाहरण संकलित कर देगा के साथ इस ले रहा है।

+0

यह interessting है। लेकिन मुझे यहां पैटर्न द्वारा आपका मतलब क्या नहीं मिलता है। क्या आप थोड़ा और समझा सकते हैं? – ziggystar

+0

मैंने अपना उत्तर –

+5

संशोधित कर दिया है दिलचस्प त्रुटि ... शायद आपको यह इंगित करना चाहिए कि यह विफल रहता है क्योंकि यह 'Tuple2 [Int, Int] 'के समतुल्य है, जो' Tuple2 [Any, Any] 'टाइप किया गया है? –

13

[scala] Question about naming conventions से आप

आरंभिक पूंजी पत्र एक फायदा जब पैटर्न मिलान है पढ़ सकते हैं। शुरुआती पूंजी पत्र वाले पहचानकर्ताओं को एक चर के बजाय मिलान करने के लिए मूल्यों के रूप में माना जाता है।

+0

रेफरी aioobe के लिए धन्यवाद! –

1

यदि आपको बड़ी संख्या में स्थिरांक प्रारंभ करने की आवश्यकता है और प्रत्येक के लिए val = लिखने से बचाना चाहते हैं या आप ट्यूपल आकार सीमा (22) को मार रहे हैं तो एक वर्कअराउंड मौजूद है।

अनुभाग The Scala Language Specification के 4.1 से:

एक मूल्य डी फाई nition वैल एक्स: टी = ई डी फाई एनईएस मूल्य का एक नाम के रूप में एक्स कि परिणाम ई के मूल्यांकन से। एक वैल्यू डेफिशन वैल पी 1, ..., पीएन = ई वैल्यू डेफिशन वैल्यू पी 1 = ई के अनुक्रम के लिए एक शॉर्टेंड है; ...; वैल पीएन = ई।

विनिर्देश के अनुसार, एक सब जो क्रम में प्रत्येक मान देता दाएँ हाथ पर एक अभिव्यक्ति निर्दिष्ट द्वारा बड़े अक्षरों से शुरू होने वाले नाम के साथ मूल्यों का एक अनुक्रम को प्रारंभ कर सकते हैं।

val iter = Iterator(1, 2, 3) 
val A, B, C = iter.next() 

एक और उदाहरण:

val next = { var n = 0;() => { n = n + 1; n } } 
val A, B, C, D, E, F, G, H = next() 

इस दृष्टिकोण से ऊपर इन तुच्छ मामलों में बहुत उपयोगी नहीं है। नीचे एक और अधिक उपयोगी उदाहरण है कि बिसात के 64 वर्गों में से प्रत्येक के लिए एक निरंतर initializes (स्रोत के लिए Square.scala#L31 देखें):

val squareIter = squares.iterator 
val A1, A2, A3, A4, A5, A6, A7, A8, 
    B1, B2, B3, B4, B5, B6, B7, B8, 
    C1, C2, C3, C4, C5, C6, C7, C8, 
    D1, D2, D3, D4, D5, D6, D7, D8, 
    E1, E2, E3, E4, E5, E6, E7, E8, 
    F1, F2, F3, F4, F5, F6, F7, F8, 
    G1, G2, G3, G4, G5, G6, G7, G8, 
    H1, H2, H3, H4, H5, H6, H7, H8 = squareIter.next() 
+0

धन्यवाद। महान विचार। पहला उदाहरण भी छोटा हो सकता है: वैल ए, बी, सी = (इटरेटर (1, 2, 3) .next _)() –

+1

धन्यवाद, लेकिन संक्षिप्त संस्करण पहले उदाहरण के बराबर नहीं है। अभिव्यक्ति '(Iterator (1, 2, 3) .next _)()' '1' का मूल्यांकन करती है और फिर' ए', 'बी' और' सी' '1' पर सेट की जाती है। –

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