2011-03-10 16 views
12

क्या कोई मुझे बता सकता है कि वास्तव में क्या चल रहा है? मैं पूरी तरह से इसे में अभी नहीं मिल रहा है:नामांकित तर्कों में अंडरस्कोर

val s = Seq(1D,2D,3D,4D) 
case class WithUnit(value: Double, unit: String) 
s map { WithUnit(_,"cm") } // works 
s map { WithUnit(value = _ , unit = "cm") } // error: missing parameter type for expanded function ((x$2) => value = x$2) 

मुझे लगता है कि संकलक नहीं कर सकते पैरामीटर प्रकार का अनुमान लगा क्योंकि मैं तर्क के नाम लिखा था। पर क्यों नहीं? तर्क के नाम को बताने के कारण यह और अधिक कठिन नहीं होना चाहिए ?!

धन्यवाद!

उत्तर

27

जब आप ने लिखा है:

WithUnit(value = _, unit = "cm") 

तुम्हारा मतलब करने के लिए यह करना चाहता था:

x => WithUnit(value = x, unit = "cm") 

लेकिन अगर आप त्रुटि संदेश पर विशेष ध्यान दें, तो आप देखेंगे कि संकलक नहीं था यह देखने कि जिस तरह से, यह के रूप में यह पार्स:

WithUnit(x => value = x, unit = "cm"}) 

आप देख सकते हैं, _ अधिक मज़बूती से आप चाहते थे दायरे वाला।

_ हमेशा यह सबसे कठिन गैर-degenerate गुंजाइश चुनता है। दायरे को पारदर्शी रूप से, प्रकार के संबंध में, पार्सिंग के दौरान निर्धारित किया जाता है।

गैर पतित करके, मेरा मतलब है कि संकलक नहीं था लगता है कि आप का मतलब:

WithUnit(value = x => x, unit = "cm") 

यानी गैर पतित गुंजाइश गुंजाइश अंडरस्कोर के अंतरतम समारोह कोष्टक रिश्तेदार द्वारा परिभाषित किया गया है। इस तरह के नियम के बिना संकलक यह जानने में सक्षम नहीं होगा कि कौन से फ़ंक्शन से मेल खाता है जब फंक्शंस कॉल को नेस्टेड किया जाता है।

+1

आह, मैं देखता हूं! अब मुझे गहरी समझ है .... _tightest non-degenerate scope_ ... मुझे याद होगा! धन्यवाद! –

+1

तर्कसंगत रूप से, हालांकि, यह एक बग है। 'WithUnit (_," cm ")' काम किया क्योंकि इसे आंशिक रूप से लागू फ़ंक्शन के रूप में माना जाता था, न कि अज्ञात फ़ंक्शन शाब्दिक। नामित पैरामीटर के साथ उपयोग किए जाने पर इसका इलाज नहीं किया जाता है, जो मुझे संदेह है कि सिर्फ एक निरीक्षण था। –

+1

@ डैनियल: मुझे नहीं लगता कि आप "आंशिक रूप से लागू फ़ंक्शन" और "अज्ञात फ़ंक्शन शाब्दिक" के बीच जो भेद कर रहे हैं वह मौजूद है। –

3

इस प्रयास करें:

scala> val withUnits = s map { x => WithUnit(value = x, unit = "cm") } 
withUnits: Seq[WithUnit] = List(WithUnit(1.0,cm), WithUnit(2.0,cm), WithUnit(3.0,cm), WithUnit(4.0,cm)) 

समस्या अंडरस्कोर के उपयोग सीधे एक anynymous समारोह को परिभाषित करने के लिए है।

विस्तृत विवरण chapter 8.5. Placeholder syntax in the "Programming in Scala" book में है।

+0

लिंक के लिए धन्यवाद, कभी-कभी कोई बाइबल की जांच करने के बारे में भूल जाता है;) –

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