2009-12-16 15 views
17

में मैं स्काला में एक वर्ग के लिए एक विधि को जोड़ना चाहते हैं, मैं की तरह कुछ करने की ज़रूरत है RichFoo उदाहरण और इसकी विधि को कॉल करें।को समझना क्यों "मेरी लाइब्रेरी दलाल" इस तरह से परिभाषित किया गया था स्काला

मैं क्यों यह रूबी के लिए इसी प्रकार परिभाषित नहीं किया गया था समझने के लिए कोशिश कर रहा हूँ:

override class Foo { 
    def newMethod = bar 
} 

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

ऐसा लगता है कि इसमें कम टाइपिंग शामिल है, मुझे नामों का आविष्कार करने की आवश्यकता नहीं है, और बेहतर प्रदर्शन (विधि को कॉल करने और ऑब्जेक्ट बनाने) नहीं है। कुछ भी अंतर्निहित रूपांतरण विधि अतिरिक्त विधि के अंदर किया जा सकता है।

मुझे यकीन है कि मुझे कुछ याद आया है और मैं इसमें अंतर्दृष्टि प्राप्त करना चाहता हूं।

+0

करता रूबी वास्तव में बाहर इस मामले में स्काला करते हैं, या आप अटकलें कर रहे हैं कि एक खुला वर्ग कार्यान्वयन एक बंद के रूप में तेजी से बनाया जा सकता है? –

+3

मैं एक मुखौटा का सुझाव देता हूं जो ऐसा लगता है कि आप कक्षा को फिर से खोल रहे हैं, लेकिन वास्तव में केवल स्थिर तरीकों को कॉल करते हैं। स्कैला कंपाइलर हर समय ऐसी चीजें करता है (लक्षण एक इंटरफ़ेस में संकलित होते हैं और स्थिर विधियों वाले वर्ग)। मैं अनुमान लगाता हूं कि मौजूदा अंतर्निहित डीईएस – IttayD

उत्तर

13

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

अद्यतन अक्टूबर 2011:

एक नया उपयोग के इस मामले वाक्य रचना चीनी जोड़ने के लिए प्रस्ताव दिया गया है: http://scala.github.com/sips/pending/implicit-classes.html

+0

मुझे लगता है कि आप सही हैं। – IttayD

+1

आपका उत्तर सही है। मैं यह इंगित करना चाहता था कि वास्तव में, स्कैला कंपाइलर (जिसे स्कैला-वर्चुअलाइज्ड कहा जाता है) के लिए एक प्रयोगात्मक विस्तार है जो कम वर्ग लिखकर मौजूदा कक्षाओं में विधियों को जोड़ने का समर्थन करता है - कुछ उदाहरण खोजने के लिए इस कक्षा में "def infix_ +" की तलाश करें : https://github.com/TiarkRompf/virtualization-lms-core/blob/e11ee5c5c9eb5d00e38927f5f1722bc956e8615d/src/ppl/StringOps.scala स्कैला-वर्चुअलाइज्ड अन्य सुविधाओं का भी समर्थन करता है, जिसके लिए सबसे अच्छा संदर्भ (हालांकि अधूरा) है : https://github.com/tiarkrompf/scala-virtualized/wiki – Blaisorblade

8

स्पष्ट रूप से आयात करने और इसे नाम देने के बिना आप उस विधि को दायरे में प्रवेश करने से कैसे रोकते हैं? वास्तव में, प्रोग्राम कैसे पता लगा सकता है कि ऐसा करने के बिना किन तरीकों को जोड़ा गया था?

जब आप तीन अलग-अलग पुस्तकालयों का उपयोग करते हैं, जिनमें से दो एक असंगत तरीके से तीसरे स्थान को जोड़ते हैं, तो आप नियंत्रण में अंतर्निहित किए बिना इसके आसपास कैसे पहुंचेंगे?

इसके अलावा, बेहतर प्रदर्शन संभव नहीं है, क्योंकि JVM किसी मौजूदा वर्ग को बदलने की अनुमति नहीं देता है। सबसे अच्छा, आप एक नाम का आविष्कार नहीं करने और क्या किया जा रहा है इसे नियंत्रित करने में सक्षम नहीं होने की लागत पर कम टाइप करने का लाभ प्राप्त कर सकते हैं।

एक अंतिम टिप्पणी के रूप में, आप कम करना चाहते हैं, आप कर सकते हैं:

implicit def fooBar(f: Foo) = new { def newMethod = bar } 
+2

की तुलना में यह कम कोडिंग और तेज है, इसके बजाय मैं फू के ओवरराइड आयात करता हूं। मैंने कक्षा को बदलने का सुझाव नहीं दिया। मैंने सुझाव दिया कि foo.bar को com.my.package.Foo.bar (foo) में परिवर्तित कर दिया जाएगा। आपका अंतिम उदाहरण है प्रतिबिंब – IttayD

+4

के माध्यम से newMethod को कॉल करना 'नया {...} 'चीज एक संरचनात्मक प्रकार है। इसके साथ सावधान रहें: इसकी विधियों को प्रतिबिंब के माध्यम से बुलाया जाता है, जो इसे धीमा कर देता है। Http://stackoverflow.com/questions/3119580/scala-equivalent-of-csharps-extension-methods/3119671#3119671 – Jesper

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