2010-07-13 17 views
6

से http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-6स्काला ActionListener/अज्ञात फ़ंक्शन प्रकार मेल नहीं खाता

val button = new JButton("test") 
button.addActionListener{ e:ActionEvent => println("test") } 
add(button) 

उच्च क्रम-समारोह उदाहरण में पाया गया कि के समान कोड लागू करने के लिए प्रयास कर रहा है निम्नलिखित

error: type mismatch; 
found : (java.awt.event.ActionEvent) => Unit 
required: java.awt.event.ActionListener 
    button.addActionListener{ e:ActionEvent => println("test") } 
             ^

इस पर सच है की ओर जाता है कम से कम मेरे सिस्टम पर स्कैला कंपाइलर संस्करण 2.7.6. फ़ाइनल के साथ। मैं एक अज्ञात एक्शनलिस्टर को स्पष्ट रूप से कार्यान्वित करने के जावा-स्टाइल तरीके में जो चाहता हूं उसे प्राप्त करने में सक्षम हूं।

button.addActionListener(new ActionListener() { 
    def actionPerformed(e:ActionEvent) { println("test") } 
}) 

जहां तक ​​मैं समझता हूँ, स्काला बतख टाइपिंग का उपयोग करने के ActionListener अनावश्यक के इस स्पष्ट कार्यान्वयन प्रस्तुत करना करने में सक्षम होना चाहिए; तो यह यहाँ क्यों काम नहीं कर रहा है? इस बिंदु पर मेरे पास बतख-टाइपिंग का कोई व्यावहारिक अनुभव नहीं है।

उत्तर

11

डक-टाइपिंग के कारण ऐसा नहीं है कि आपका कोड काम नहीं करता है। यह है क्योंकि स्कैला की प्रकार प्रणाली इंटरफेस प्रकार और डिफ़ॉल्ट रूप से फ़ंक्शन प्रकार के बीच अंतर्निहित रूपांतरण प्रदान नहीं करती है। हालांकि, यदि निम्नलिखित निहित रूपांतरण परिभाषित किया गया है, तो आपका कोड सही तरीके से काम करता है।

implicit def toActionListener(f: ActionEvent => Unit) = new ActionListener { 
    def actionPerformed(e: ActionEvent) { f(e) } 
} 

यह निहित रूपांतरण (एक्शनइवेंट => यूनिट) से एक्शनलिस्टर में रूपांतरण प्रदान करता है।

+1

प्रशंसकवाद के रूप में नहीं, लेकिन यह ध्यान देने योग्य है कि ग्रोवी और विभिन्न जावा क्लोजर प्रस्तावों में उचित फ़ंक्शन प्रकारों से एकल विधि इंटरफेस में अंतर्निहित रूपांतरण शामिल थे। यह रननेबल या तुलनात्मक जैसे इंटरफेस के लिए बहुत सुविधाजनक है। स्कैला में, आपको या तो हाथ से यह रूपांतरण करने की ज़रूरत है, या इसे करने के लिए पिंपीड लाइब्रेरी पर भरोसा करना है। –

+1

@ डेव हां ... यदि प्रकार मेल नहीं खाता है, तो ऑटो-कास्ट करें। मुझे लगता है कि यह स्पष्ट होना चाहिए कि स्कैला ने इस तरह क्यों नहीं चुना। –

+0

ओह, निश्चित रूप से। यह केवल ग्रोवी और जावा के लिए समझ में आता है क्योंकि उनमें मौजूदा पुस्तकालयों को विस्तारित करने के किसी भी अच्छे तरीके शामिल नहीं हैं, इसलिए उन्हें विरासत जावा गैर-दर्दनाक के साथ काम करने के लिए इस ऑटो-रूपांतरण की आवश्यकता है। स्कैला में विरासत पुस्तकालयों के लिए पिंप्स हैं, और एकल पुस्तकालयों को एकल-विधि इंटरफेस पर कार्यात्मक रूपों के पक्ष में लिखने के लिए लिखा जाना चाहिए (और हो रहा है)। –

4

स्कैला बतख-टाइप नहीं है। इसमें वैकल्पिक, स्पष्ट संरचनात्मक-टाइपिंग है, लेकिन इसका कोई संबंध नहीं है कि आपका कोड क्यों काम नहीं करता है।

आपका कोड काम नहीं करता है, क्योंकि JButton.addActionListener को ActionListener इसकी तर्क के रूप में अपेक्षा करता है, फ़ंक्शन नहीं। यहां तक ​​कि यदि स्कैला को डकटाया गया था, तो आप केवल एक फ़ंक्शन पास नहीं कर पाए क्योंकि ActionListener पर उपलब्ध एक ही तरीके फ़ंक्शन पर उपलब्ध नहीं हैं।

ध्यान दें कि लेख कहता है "चलो एक आनंददायक पल के लिए मान लें कि हम स्काला के सिंटैक्स का पूर्ण लाभ लेने के लिए स्विंग को फिर से लिख सकते हैं", यानी लेख आपको वास्तविक कोड दिखाने का दावा नहीं करता है।

हालांकि स्कैला के पास इसका स्वयं का स्विंग पैकेज है (scala.swing) जिसमें कक्षाएं शामिल हैं जो उनके जावा समकक्षों की तुलना में अधिक "स्केलिश" हैं।

+0

आह, लेख से उद्धरण वास्तव में प्रासंगिक है। मुझे लगता है कि जनता में एक प्रश्न पूछना मेरे हिस्से पर कुछ बुनियादी पढ़ने की समझ विफलता का खुलासा करने के लिए बाध्य था ... फिर भी, आपका उत्तर जानकारीपूर्ण है। धन्यवाद। – PeterT

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