2010-05-20 14 views
6

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

abstract class Shape 
case class Point(x: Int, y: Int) extends Shape 
case class Polygon(points: Point*) extends Shape 

अब मान लीजिए कि मैं एक बहुभुज बनाने: तो फिर

val poly = new Polygon(new Point(2,5), new Point(7,0), new Point(3,1)) 

अगर मैं स्थान और छोटी संभव आयत के आकार कि बहुभुज को रख सकती निर्धारित करने के लिए प्रयास करते हैं, मैं विभिन्न मिल त्रुटियां जो मुझे समझ में नहीं आती हैं।

नीचे विभिन्न प्रयासों के स्निपेट और उनके द्वारा उत्पन्न किए गए संबंधित त्रुटि संदेश हैं।

val upperLeftX = poly.points.reduceLeft(Math.min(_.x, _.x)) 

त्रुटि देता है:
":" का विस्तार कार्य के लिए लापता पैरामीटर प्रकार ((एक्स $ 1) => x $ 1.x) "

val upperLeftX = 
     poly.points.reduceLeft((a: Point, b: Point) => (Math.min(a.x, b.x))) 

इस त्रुटि देता है टाइप मिस्चैच;
मिला: (प्वाइंट, पॉइंट) => Int
आवश्यक: (कोई भी, प्वाइंट) => कोई भी
"

मैं इन दोनों त्रुटि संदेशों के बारे में बहुत उलझन में हूं। अगर कोई और स्पष्ट रूप से समझा सकता है कि मैं गलत तरीके से क्या कर रहा हूं, तो मैं वास्तव में इसकी सराहना करता हूं। हां, मुझे लगता है कि दूसरी त्रुटि कहती है कि मुझे "कोई भी" टाइप करने की ज़रूरत है, लेकिन मुझे समझ में नहीं आता कि वास्तव में एक बदलाव को कैसे कार्यान्वित किया जाए, जिसकी मुझे आवश्यकता होगी। स्पष्ट रूप से बस "ए: पॉइंट" से "ए: कोई भी" बदलना एक व्यवहार्य समाधान नहीं है, तो मुझे क्या याद आ रही है?

उत्तर

6

reduceLeft के प्रकार reduceLeft[B >: A](op: (B, A) => B): B है, APoint है, और आप (a: Point, b: Point) => (Math.min(a.x, b.x)) करने के लिए इसे लागू करने के लिए कोशिश कर रहे हैं।

इस प्रकार संकलक कारण हैं:।।? Math.min(a.x, b.x) रिटर्न Int, तो IntB की एक उप-प्रकार होना चाहिए और B भी की Point एक महाप्रकार होना चाहिए क्यों B संचायक के प्रकार है, और इसका प्रारंभिक मान आपके Polygon में पहला Point है। यह B >: A का अर्थ है।

Int और Point का एकमात्र सुपरटेप Any है; इसलिए BAny है और op का प्रकार (Any, Point) => Any होना चाहिए, जैसा कि त्रुटि संदेश कहता है।

+0

ठीक है ... मुझे लगता है कि मैं वास्तव में इसे समझ गया। स्पष्टीकरण के लिए धन्यवाद! – klactose

2

यह स्काला 2.8.0.RC2

scala> abstract class Shape 
defined class Shape 

scala> case class Point(x: Int, y: Int) extends Shape 
defined class Point 

scala> case class Polygon(points: Point*) extends Shape 
defined class Polygon 

scala> val poly = new Polygon(new Point(2,5), new Point(7,0), new Point(3,1)) 
poly: Polygon = Polygon(WrappedArray(Point(2,5), Point(7,0), Point(3,1))) 

scala> val upperLeftX = poly.points.reduceLeft((a:Point,b:Point) => if (a.x < b.x) a else b) 
upperLeftX: Point = Point(2,5) 

reduceLeft यहाँ प्रकार (Point, Point) => Point के एक समारोह की आवश्यकता है। (अधिक सटीक (B, Point) => BPoint करने के लिए एक कम बाध्य साथ B साथ। विधि reduceLeft पर Scaladoc देखें।

+0

यह एक प्वाइंट देता है, लेकिन मेरी उदाहरण में मैं एक इंट (छोटी वापस जाने के लिए प्रयास कर रहा हूँ होने के लिए x- निर्देशांक सटीक)। और मेरा मानना ​​है कि मेरी समस्या झूठ बोल रही है क्योंकि संकलक भ्रमित हो रहा है क्योंकि किस प्रकार इसे वापस करना चाहिए। अपने कोड में फेरबदल एक इंट वापस जाने के लिए (जो कि मैं क्या जरूरत है): वैल upperLeftX = poly.points.reduceLeft ((क: प्वाइंट, ख: प्वाइंट) => अगर (कुल्हाड़ी klactose

+0

बस इसे आजमाएं: 'val upperLeftX = poly.points.reduceLeft ((ए, बी) => यदि (कुल्हाड़ी

+1

scala2.8: वैल upperLeftX = poly.points.map (_। X) .min – Eastsun

2

एक और विकल्प poly.points.foldLeft(Int.MaxValue)((b, a) => Math.min(b, a.x)) है, जो स्कैला 2.7.x के साथ भी काम करना चाहिए।मतभेद reduceLeft संस्करण की तुलना में कर रहे हैं

  • आप एक शुरुआत मूल्य
  • तत्वों के प्रकार और दोनों के बीच कोई कमी नहीं है (हमारे मामले में Int.MaxValue, किसी भी वास्तविक डेटा छोटे या इस के बराबर होगा) परिणाम के प्रकार, कम करने के लिए निचले बाध्य बाधा की तरह Left फिर भी Eastsun का समाधान अधिक सुरुचिपूर्ण है।

BTW अगर आप पहले से मामले श्रेणियां होती हैं नए कीवर्ड ommit कर सकते हैं और साथी वस्तु में स्वचालित रूप से उत्पन्न कारखाने विधि का उपयोग कर सकते हैं। इसलिए पॉली बनाने वाली रेखा val poly = Polygon(Point(2,5), Point(7,0), Point(3,1)) बन जाती है, जो पढ़ने के लिए थोड़ा आसान है।

+0

धन्यवाद, मैं उस जानकारी को नए कीवर्ड के बारे में दिमाग में रखूंगा – klactose

+0

@ राहुल: सुधार के लिए धन्यवाद। मैं जल्द ही उस की तलाश में था, लेकिन इसे नहीं मिला :-) –

1

मैं देख रहा हूँ कि हर कोई दूसरा टुकड़ा पर latched है लगता है, इसलिए मैं पहले एक जवाब देंगे:

val upperLeftX = poly.points.reduceLeft((a, b) => Math.min(a.x, b.x)) 

हालांकि, वह नहीं है:

val upperLeftX = poly.points.reduceLeft(Math.min(_.x, _.x)) 

आपको लगता है कि इसका मतलब यह करने का इरादा अंडरस्कोर कैसे काम करता है। अंडरस्कोर के कई अर्थ हैं, लेकिन उनमें से दो यहां प्रासंगिक हैं।

सबसे पहले, इसका मतलब आंशिक फ़ंक्शन एप्लिकेशन हो सकता है। उदाहरण के लिए, Math.min(_, 0)आंशिक रूप सेmin पर पैरामीटर लागू करता है, और शेष कार्य को लागू करने वाले फ़ंक्शन को वापस कर देता है। दूसरे शब्दों में, यह x => Math.min(x, 0) के बराबर है, जो एनोटेशन प्रकार को अनदेखा कर रहा है। किसी भी दर पर, इसका अर्थ केवल लागू होता है यदि अंडरस्कोर पैरामीटर के एक (या अधिक) के स्थान पर स्वयं ही होता है।

हालांकि, आपके उदाहरण में यह मामला नहीं है, क्योंकि आपने अंडरस्कोर के बाद .x जोड़ा है। यदि अंडरस्कोर किसी भी प्रकार की अभिव्यक्ति में प्रकट होता है, जैसे कि आपके उदाहरण में विधि कॉल, तो अंडरस्कोर एक अज्ञात फ़ंक्शन में पैरामीटर के लिए प्लेसहोल्डर है।

इस दूसरे अर्थ में अज्ञात फ़ंक्शन की सीमाओं को समझना विशेष रूप से महत्वपूर्ण है। विशेष रूप से, अज्ञात फ़ंक्शन को सबसे निचले कोष्ठक या घुंघराले ब्रैकेट द्वारा सीमित किया जाएगा जो इसे संलग्न करता है, या किसी भी अल्पविराम से।

अब, पहले स्निपेट में अभिव्यक्ति के उस नियम को लागू करने का मतलब है कि snipper इस तरह संकलक द्वारा देखा जाता है:

val upperLeftX = poly.points.reduceLeft(Math.min(a => a.x, b => b.x)) 

तो, वहाँ दो समस्याओं यहाँ हैं। सबसे पहले, आप दो युगल के बजाय दो कार्यों को min पर पास कर रहे हैं। दूसरा, क्योंकि min फ़ंक्शंस प्राप्त करने की अपेक्षा नहीं कर रहा है, संकलक इस बात का अनुमान नहीं लगा सकता कि इन कार्यों का प्रकार क्या हो सकता है। चूंकि आपने ऊपर a और b के प्रकारों के बारे में कोई जानकारी प्रदान नहीं की है, तो यह इसके बारे में शिकायत करता है।

आप इस तरह के प्रकार प्रदान किया था, तो त्रुटि संदेश कुछ इस तरह होगा:

<console>:6: error: type mismatch; 
found : Int 
required: ?{val x: ?} 
संबंधित मुद्दे