2011-03-28 14 views
6

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

class ValueGenerator { 
    def value() = { 
     "1" 
    } 
    def value(line: String) = { 
     line 
    } 
} 

मैं value उचित हस्ताक्षर के साथ जब मैं जरूरत कहेंगे, परिणाम मैं प्राप्त करने के लिए। विधियों के समान हस्ताक्षर होते हैं, क्योंकि वे तार्किक रूप से समान क्रियाओं के अनुरूप होते हैं। ओओ में, मैं ऑब्जेक्ट संदर्भ के चारों ओर गुज़रता हूं, और ValueGenerator ऑब्जेक्ट प्राप्त करने वाली विधियों से स्थिति के आधार पर दाएं value पर कॉल किया जाएगा। जहां तक ​​मैं देख सकता हूं, कम से कम यह मेरी प्रवृत्ति है, कि स्काला में मानक विधि के चारों ओर पास करना है। लेकिन इस मामले में, हालांकि विधियां एक ही काम करती हैं, उनके पास एक ही हस्ताक्षर नहीं है, इसलिए एक-दूसरे के लिए प्रतिस्थापित नहीं किया जा सकता है (या वे कर सकते हैं?)। दूसरे शब्दों में, क्या प्रेषक विधि फ़ंक्शन के हस्ताक्षर के बावजूद फ़ंक्शन को भेजने का निर्णय ले सकता है? यह असंभव लगता है क्योंकि रिसीवर यह नहीं जानता कि इसे कैसे शुरू किया जाए। इस तरह की स्थिति में सही कार्रवाई क्या है। या क्या कोई अपने आंत वृत्ति के साथ जाता है? जब ओओ बनाम एफबी की बात आती है तो क्या अंगूठे का नियम होता है?

एक साइड नोट के रूप में, यह देखना दिलचस्प था कि मेरा एक मित्र जो स्कैला सीख रहा है, इस मुद्दे पर मेरे बारे में सटीक विचार (या इसकी कमी) था।

class ValueGenerator { 
    def value(line: String = "1") = { 
    line 
    } 
} 

आरईपीएल सत्र:

+2

विधियों में एक ही हस्ताक्षर नहीं है: कोई स्ट्रिंग प्रकार का एक तर्क लेता है, दूसरा कोई तर्क नहीं लेता है। जेवीएम स्पेक की धारा 2.10.2 से: "विधि के हस्ताक्षर में विधि का नाम और विधि के औपचारिक पैरामीटर (§2.10.1) के प्रकार और प्रकार शामिल हैं [...]" –

+0

इसके अलावा, आप ध्यान दें कि एक विधि कुछ है, एक समारोह कुछ और है। आप आसपास के तरीकों को पारित नहीं करते हैं, आप केवल कार्य को पास कर सकते हैं। हालांकि, आप एक समारोह में एक विधि उठा सकते हैं। –

+0

यह भी देखें http://jim-mcbeath.blogspot.com/2009/05/scala-functions-vs-methods.html –

उत्तर

4

कोड आपके द्वारा दिए गए, वहाँ कोई कारण नहीं है कि आप दो अलग-अलग विधि हस्ताक्षर की आवश्यकता है

scala> new ValueGenerator() 
res1: ValueGenerator = [email protected] 

scala> res1.value("Foo") 
res2: String = Foo 

scala> res1.value() 
res3: String = 1 

आप केवल यह कर सकते हैं ध्यान रखें तरीकों के साथ। कार्य डिफ़ॉल्ट तर्क का समर्थन नहीं करते:

scala> val f = res1.value(_) 
f: (String) => String = <function1> 

scala> f("Bar") 
res5: String = Bar 

scala> f() 
***Oops*** 

scala> val f = (line: String) => line  
f: (String) => String = <function1> 

scala> val f = (line: String = "1") => line 
***Oops*** 
9

वे एक ही हस्ताक्षर की जरूरत नहीं है, और आम तौर पर आप तरीकों कि अलग-अलग नाम है करने के लिए एक ही हस्ताक्षर नहीं करना चाहती। ओवरलोडिंग आपको बहुत कम खरीदती है और आपको बहुत अधिक खर्च करती है (अर्थात्, अनुमान और निहित संकल्प टाइप करें)।

उस ने कहा, उन्हें एक दूसरे के लिए प्रतिस्थापित नहीं किया जा सकता है क्योंकि उनके पास एक ही प्रकार नहीं है। यदि आप इन विधियों को फ़ंक्शंस में कनवर्ट करेंगे, तो आपके पास Function0[String] टाइप होगा और दूसरे के पास Function1[String, String] होगा।

2

जहां तक ​​मैं देख सकता हूं, कम से कम यह मेरी प्रवृत्ति है, कि स्कैला में मानक विधि के चारों ओर पास करना है।

मुझे संदेह है कि यह आदर्श है (आप ऐसा क्यों सोचते हैं?) या स्कैला में इसके लिए भी एक आदर्श है।

लेकिन इस मामले में, हालांकि विधियां एक ही काम करती हैं, उनके पास एक ही हस्ताक्षर नहीं है, इसलिए एक दूसरे के लिए प्रतिस्थापित नहीं किया जा सकता है (या वे कर सकते हैं?)। दूसरे शब्दों में, क्या प्रेषक विधि फ़ंक्शन के हस्ताक्षर के बावजूद फ़ंक्शन को भेजने का निर्णय ले सकता है?

वे एक दूसरे के लिए प्रतिस्थापित नहीं किया जा सकता क्योंकि वे विभिन्न हस्ताक्षर है, ताकि वे विभिन्न प्रकार की है।

परिदृश्य है कि आप काम करने के OO रास्ता के लिए एक सही फिट की तरह लगता है का वर्णन: बस ValueGenerator वस्तु गुजरती हैं और ग्राहक तय कौन सी विधि है कि वस्तु में कॉल करने के लिए करते हैं।

+0

ठीक है, मुझे नहीं पता कि मानक क्या है, लेकिन डिजाइन पैटर्न और सर्वोत्तम प्रथाएं हैं किसी दिए गए भाषा, और दिए गए समय सभी भाषाओं को इस तरह के उपयोग पर कमजोर रूप से अभिसरण किया जाता है। उदाहरण के लिए, इस मामले में, मैं इसे ओओ तरीके से कर सकता था, लेकिन मैं कक्षा में 'लाइन' भी स्टोर कर सकता था, और इसके साथ निपटने के लिए' मूल्य 'के लिए केवल एक ही विधि है, जिसे मैं पास कर सकता हूं। एक ही चीज़ को पूरा करने के लिए दो अलग-अलग दृष्टिकोण। – delmet

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