2010-01-14 12 views
12

मैं नियमों पर थोड़ी कमजोर हूं कि जब आपको फ़ंक्शन के रूप में उपयोग करने के लिए _ की आवश्यकता होती है। उदाहरण के लिए, निम्नलिखित में Foo और Nil के :: के बीच कोई अंतर क्यों है?मुझे _ के साथ विधि नाम का पालन करने की आवश्यकता क्यों है?

def square(n: Int) = n * n 
object Foo { def ::(f: Int => Int) = f(42) } 

// ... 

scala> Foo.::(square) 
res2: Int = 1764 

scala> Nil.::(square) 
<console>:6: error: missing arguments for method square in object $iw; 
follow this method with `_' if you want to treat it as a partially applied function 
    Nil.::(square) 
     ^
scala> Nil.::(square _) 
res3: List[(Int) => Int] = List(<function1>) 

उत्तर

15

जब आप एक आंशिक रूप से लागू किया समारोह अभिव्यक्ति में सभी मापदंडों को छोड़ देते हैं, तो आप के साथ _जब तक संकलक जगह है जहाँ आप इसका इस्तेमाल में एक समारोह प्रकार की आवश्यकता है इसे का पालन करने की जरूरत है।

जब आप :: पर Foo पर विधि कॉल करते हैं, तो संकलक पैरामीटर के लिए Int => Int प्रकार की अपेक्षा करता है। तो आप उस स्थिति में square के बाद अंडरस्कोर को सुरक्षित रूप से छोड़ सकते हैं।

हालांकि, ::Nil पर विधि प्रकार का पैरामीटर ले सकता है। इसलिए यह मानने के बजाय कि आप आंशिक रूप से फ़ंक्शन को लागू करने के लिए चाहते हैं, यह तब तक शिकायत करता है जब तक आप इसे _ जोड़कर बिल्कुल स्पष्ट नहीं करते।

तो ये नियम हैं ... मैं आपको के बारे में वास्तव में प्रबुद्ध नहीं कर सकता हूं क्यों ये नियम हैं; हो सकता है कि कोई और जिसके पास कंपाइलर, टाइप सिस्टम और भाषा डिज़ाइन का बेहतर ज्ञान हो, आपको बताएगा कि क्यों। लेकिन मुझे लगता है कि इन नियमों के बिना, कई स्थानों पर आकस्मिक अस्पष्टता का खतरा होगा।

+2

धन्यवाद। स्काला भाषा स्पेक का सिर्फ एक हिस्सा मिला जो स्कैला 2.0 के लिए परिवर्तन नोट्स में "क्यों" के लिए कुछ औचित्य देता है: "कार्यों के लिए विधियों के पूर्ण रूपांतरण के नियम (§6.25) को कड़ा कर दिया गया है। पहले, एक पैरामीटरयुक्त विधि का उपयोग किया गया था क्योंकि एक मान हमेशा एक समारोह में रूपांतरित हो गया था। इससे अप्रत्याशित परिणाम हो सकते हैं जब विधि तर्क कहां भूल गए हैं। उदाहरण के लिए नीचे दिए गए कथन पर विचार करें: दिखाएं (x.toString) ... " –