2010-07-05 13 views
17

में इन्फिक्स विधि कॉल और विपक्ष ऑपरेटर (: :) को समझना स्कैला प्रोग्रामिंग भाषा के लिए काफी नया है, और मैं अपने दिमाग में फंस गया कुछ कोशिश कर रहा था, जबकि मैं here पर व्याख्यान नोट्स का पालन कर रहा था। ,स्केल

मैं एक छद्म यादृच्छिक संख्या जनरेटर बना लिया है तो एक यादृच्छिक मूल्य की एक सूची बनाने की कोशिश की:

मुझे लगता है कि मैं वास्तव में नहीं समझ सकता है कैसे विपक्ष ऑपरेटर काम करता है, यहाँ कुछ चीजें मैंने कोशिश कर रहे हैं:

scala> val gen = new java.util.Random 
gen: java.util.Random = [email protected] 

scala> gen nextInt 3 :: Nil 
<console>:7: error: type mismatch; 
found : List[Int] 
required: Int 
     gen nextInt 3 :: Nil 
        ^

लेकिन यह सूची (3) को अगली विधि में पास करने का प्रयास किया। जब मैं paratheses इस्तेमाल किया, वहाँ कोई समस्या नहीं

scala> (gen nextInt 3) :: Nil 
res69: List[Int] = List(1) 

मैं निष्पादन आदेश के बारे में उत्सुक था, तो मैं यह

scala> def pr(i:Int):Int = { println(i); i } 
pr: (i: Int)Int 

scala> pr(1) :: pr(2) :: pr(3) :: Nil 
1 
2 
3 
res71: List[Int] = List(1, 2, 3) 

जाँच करने के लिए के रूप में आउटपुट में देखा एक समारोह बनाया है, निष्पादन के आदेश के रूप में एक ही है उपस्थिति का क्रम। फिर मैंने सोचा कि यह 'nextInt' समारोह के बारे में हो सकता है, तो मैं निम्नलिखित की कोशिश की:

scala> 1 + 2 :: Nil 
res72: List[Int] = List(3) 

यह पहली बार इसके मार डाला, और कहा कि विपक्ष के बाद मार डाला जाता है। तो यहां सवाल है: gen nextInt 3 :: Nil और 1 + 2 :: Nil के बीच क्या अंतर है?

उत्तर

39

यहां चिंता की दो चीजें हैं: precedence और fixity। जैसा कि sepp2k ने उल्लेख किया है, स्टैक ओवरफ्लो पर यह प्रश्न प्राथमिकता बताता है, मानते हैं कि नियम उद्धृत किए गए हैं, पर्याप्त नहीं हैं, और स्कैला 2.7 से स्कैला 2.8 में बहुत छोटे बदलाव हुए थे। अंतर, ज्यादातर ऑपरेटरों को = में समाप्त होने पर चिंता करते हैं।

फिक्सिटी के रूप में, स्कैला में लगभग सबकुछ बाएं से दाएं पढ़ा जाता है, जो प्रोग्रामर का उपयोग किया जाता है। स्कैला में, हालांकि, : में समाप्त होने वाले ऑपरेटरों को बाईं ओर दाईं ओर पढ़ा जाता है।

लें, फिर, इस उदाहरण:

1 + 2 :: Nil 

पहले, पूर्वता। सबसे अधिक प्राथमिकता क्या है, + या :? तालिका के अनुसार, + पर : से अधिक प्राथमिकता है, इसलिए अतिरिक्त पहले किया जाता है। इसलिए, अभिव्यक्ति इस के बराबर है:

((1).+(2)) :: Nil 

अब वहाँ कोई पूर्वता संघर्ष है, लेकिन जब से ::: में समाप्त होता है, यह एक विभिन्न स्थिरता है।यह दाएं से बाएं पढ़ने के लिए है, इसलिए:

Nil.::((1).+(2)) 

दूसरी ओर, इस में:

gen nextInt 3 :: Nil 

ऑपरेटर ::nextInt पर पूर्वता है, क्योंकि : सभी पत्र पर पूर्वता है। इसलिए, और उसके स्थिरता को याद है, यह हो जाता है:

gen nextInt Nil.::(3) 

कौन सा तो हो जाता है

gen.nextInt(Nil.::(3)) 

जो बिंदु पर त्रुटि स्पष्ट है।

पुनश्च: मैं 1.+(2) के बजाय (1).+(2) लिख रहा हूँ, क्योंकि इस लेखन के समय, 1. एक डबल संख्या के रूप में व्याख्या की है, 1.+(2) जोड़ने में कोई इन्फ़िक्स अभिव्यक्ति बनाने डबल 1.0 2. करने के लिए इस वाक्य रचना स्काला के रूप में हटा दिया गया है 2.10.0, और शायद स्कैला 2.11 पर मौजूद नहीं होगा।

+0

आपके विस्तृत उत्तर के लिए धन्यवाद, इसने मुझे कई अन्य चीजों के बारे में भी कई संकेत दिए। लेकिन मेरे पास एक और सवाल है: संकलक मेरे शुरुआती प्रश्न में दिए गए तीसरे कोड खंड में अभिव्यक्ति की व्याख्या कैसे करता है; संश्लेषण के मामले में? क्योंकि फ़ंक्शन पीआर का उपयोग करके पता चला है कि नियम बाएं से दाएं क्रम में निष्पादित किए जाते हैं। – ciuncan

+1

यह सही है, फ़ंक्शन कॉल का मूल्यांकन बाएं से दाएं से किया जाता है। ऐसा इसलिए है क्योंकि 'pr (X)' '::' के तर्क अभिव्यक्ति हैं और इन्हें पहले उपस्थिति के क्रम में मूल्यांकन किया जाता है और फिर मान विधि को पास किया जाता है। 'पीआर (1) :: पीआर (2) :: पीआर (3) :: नील 'प्रिंट 1 2 3. लेकिन' शून्य ::(pr(3)).::(pr(2))। : :(पीआर (1)) 'प्रिंट 3 2 1. लेकिन दोनों लौट रहे हैं 'सूची (1, 2, 3)' –

+0

@ciuncan मुझे नहीं पता। यह हो सकता है कि सही फिक्सिटी के साथ ऑपरेटर नोटेशन एक मूल्यांकन आदेश को डॉट नोटेशन के साथ संभव नहीं बनाता है, या हो सकता है कि संकलक '::' कॉल को अनुकूलित करता है लेकिन मूल्यांकन आदेश से संबंधित एक बग है। –

3

यह प्राथमिकता निष्पादन आदेश नहीं है। +:: से अधिक प्राथमिकता है, इसलिए a + b :: c पार्स (a + b) :: c के रूप में। हालांकि नियमित नामों के साथ इंफिक्स विधि कॉल कम प्राथमिकता है, इसलिए a foo b c पार्स a foo (b c) के रूप में।

स्केल में उनकी प्राथमिकता द्वारा आदेशित ऑपरेटरों की सूची के लिए this question देखें।

+1

आपकी व्याख्या के लिए धन्यवाद। वरीयता वह थी जिसे मैंने अभी सोचा था। – ciuncan