2009-10-20 12 views
9

सी, जावा और कई अन्य भाषाएं वापसी मूल्यों पर ध्यान नहीं देती हैं।क्यों भाषाएं वापसी मूल्य से विधियों को ओवरलोड करने की अनुमति नहीं देती हैं?

int i = func() 
float f = func() 
int func() { return 5 } 
float func() { return 1.3} 

उपरोक्त कानूनी क्यों नहीं है? क्या यह प्रोग्राम

int i = func(func(func(func2(func3())))) //you dont know what you are getting 

क्या यह एक कंपाइलर लिखना मुश्किल है? क्या वहां और भाषा असंबद्धता है? क्या कोई ऐसी भाषा है जो उपर्युक्त कर सकती है?

+0

क्या आपने LISP की कोशिश की है ?? यदि कोशिश नहीं की जाती है, तो यह आपकी समस्या का समाधान कर सकती है। – Zinx

+0

संभावित डुप्लिकेट [वापसी प्रकार द्वारा फ़ंक्शन ओवरलोडिंग?] (Http://stackoverflow.com/questions/442026/function-overloading-by-return-type) – nawfal

उत्तर

14

मान लें कि यह अनुमति दी गई थी चलो, जो एक होगा इस कॉल:

func(); 

कि नहीं हो सकता पूरा जवाब है, लेकिन मुझे विश्वास है कि एक कारण है कि यह कानूनी नहीं है।

+1

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

+2

मुझे लगता है कि वापसी मूल्यों को संभालने के लिए यह बुरा अभ्यास है। यह एक अपवाद फेंक दिया जाना चाहिए या वापसी मूल्य की जांच की जानी चाहिए। हालांकि var v = func(); (सी # स्टाइल असाइनमेंट) समस्याएं पैदा कर सकता है ... (hmmmm)) –

+0

+1 मुझे var v = –

17

इस मामले के बारे में क्या?

class A implements Foo { /*...*/ } 
class B implements Foo { /*...*/ } 

A func() { return new A(); } 
B func() { return new B(); } 

Foo v = func(); // which do you call?! 

अस्पष्टता के साथ पहले से ही समस्याएं हैं जब आप एक ही फ़ंक्शन नाम को ओवरलोड करने की अनुमति देते हैं जो विभिन्न तर्क लेते हैं। वापसी प्रकार की जांच करने के साथ-साथ सही कार्य को हल करना बहुत कठिन होगा।

मुझे यकीन है कि एक भाषा इसे कार्यान्वित कर सकती है, लेकिन इससे चीजें बहुत जटिल हो जाएंगी, और आमतौर पर कोड को समझने में कठिनाई होगी।

+2

के लिए एक उपद्रव होगा, इसी तरह 'System.out.println (func () + func()) 'आउटपुट? – notnoop

+0

इससे कोड को समझने में कठिनाई होगी। +1। हो सकता है कि मैं इसे सही के रूप में चिह्नित करूं (मैं अन्य उत्तरों देखना चाहता हूं) –

+0

ओवरलोड को "पसंदीदा" के रूप में चिह्नित करने की आवश्यकता के बारे में, दूसरों के साथ केवल तभी उपयोग किया जा रहा है जब रिटर्न प्रकार तत्काल डाला जाएगा या किसी अन्य प्रकार के लिए मजबूर किया जाएगा (जिसके लिए एक अधिक सटीक अधिभार प्रदान किया जाता है), या जब रिटर्न प्रकार को अनदेखा किया जाता है (यदि आपूर्ति की जाती है तो किस मामले में 'शून्य' अधिभार का उपयोग किया जाएगा)? – supercat

6

एक सी ++ उदाहरण के लिए, पर विचार करें:

void g(int x); 
void g(float x); 
g(func()); 

अतिभारित g() कार्यों में से कौन सा ही कहा जाता है?

+1

इस मामले में यह कभी-कभी सी ++ करता है और उपयोगकर्ता को 'g ((Float_OR_int_type) func()) लिखने के लिए मजबूर करने में एक अस्पष्ट त्रुटि के साथ संकलित करता है; ' –

+0

यहां तक ​​कि इससे मदद नहीं मिलेगी। क्या होगा यदि आपके पास कई विधियां हैं जो एक प्रकार लौटाती हैं जिसे आप जिस ऑब्जेक्ट पर कास्टिंग कर रहे हैं उसे वैध रूप से डाला जा सकता है? int को फ्लोट करने के लिए डाला जा सकता है, और इसके विपरीत। – Herms

1

अधिकांश भाषाएं स्वचालित जबरन (जैसे फ्लोट + इंट) के साथ मिश्रित-मोड संचालन की अनुमति देती हैं, जहां कई व्याख्याएं कानूनी होती हैं। जबरन बिना, कई संख्यात्मक प्रकारों (लघु, int, लंबे, फ्लोट, डबल) के साथ काम करना बहुत बोझिल हो जाएगा; जबरदस्ती के साथ, रिटर्न-टाइप आधारित असंबद्धता से समझने में कठिनाई होगी।

1

इन्हें अनुमति देना समस्याएं पेश कर सकता है। उदाहरण के लिए:

int i = func2(func()); 
int func() { return 5; } 
float func() { return 1.3; } 
int func2(float a) { return a; } 
int func2(int a) { return a; } 

यह संदिग्ध है।

+0

यह निर्दिष्ट करने में क्या गलत होगा कि प्रत्येक विधि हस्ताक्षर में एक कार्यान्वयन होना चाहिए जिसे पसंदीदा के रूप में चिह्नित किया गया है, सिवाय इसके कि जब फ़ंक्शन का नतीजा या तो चर या तुरंत टाइपकास्ट को असाइन किया जा रहा हो? – supercat

3

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

+0

पर्ल के लिए कौन सा काम करता है, लेकिन पर्ल में कई चीजें हैं जो मुझे नहीं लगता कि एक और पारंपरिक भाषा में काम करेगा। उल्लेख नहीं है कि पर्ल में सामान्य अर्थ में एक प्रकार की प्रणाली नहीं है: प्रकार $ scalars, @arrays, #hashes, @typeglobs हैं, और ऐसा लगता है कि मैं एक भूल गया हूं। पूर्णांक, फ्लोट और स्ट्रिंग के बीच कोई भेद नहीं है, और ऑपरेटरों को यह पता लगाना होगा कि संख्यात्मक रूप से ($ i + 1) या स्ट्रिंग्स ($ i + "1") के साथ कार्य करना है या नहीं। –

+0

@ डेविड: मुझे नहीं लगता कि मैं अपनी प्रतिक्रिया में पर्ल के किसी भी गुण की प्रशंसा कर रहा था, न ही यह सुझाव देता हूं कि ऐसी चीजें * को अन्य भाषाओं में जोड़ा जाना चाहिए। मैं केवल सवाल के उस हिस्से का जवाब दे रहा था जो पूछता है कि वहां क्या है। वास्तव में अच्छा, संक्षिप्त, प्रत्यक्ष उदाहरण के लिए – Novelocrat

10

हां, रिटर्न प्रकारों पर ओवरलोडिंग की अनुमति एक भाषा को जटिल बनाती है। यह अधिभारित पहचानकर्ताओं (जैसे फ़ंक्शन नाम) के समाधान को जटिल बनाता है। लेकिन यह असंभव नहीं है, उदा। हास्केल उनके रिटर्न प्रकार के आधार पर फ़ंक्शन ओवरलोड करने की अनुमति देता है।

class Num a where 
    fromInteger :: Integer -> a 
    ... 

Num एक विधि fromInteger कहा जाता है एक मनमाना प्रकार है जो Num का एक उदाहरण है करने के लिए मनमाने ढंग से आकार Integer से एक समारोह है, जिसके साथ हास्केल में एक प्रकार वर्ग है। हास्केल प्रकार वर्ग तंत्र वस्तु-उन्मुख भाषाओं की कक्षा अवधारणा से अलग है। इसलिए मेरी व्याख्या अजीब लग सकती है।

लेकिन परिणाम यह है कि मैं इंटेगर से फ़ंक्शन का उपयोग कर सकता हूं और कॉलिंग संदर्भ के आधार पर, विभिन्न कार्यान्वयन संकलन समय पर chooen हैं।

टाइप सिस्टम पर शोध की एक पूरी श्रृंखला है, जिसने इस सुविधा को संभव बनाया है। इसलिए, मैं कहूंगा कि यह स्थिर रूप से टाइप की गई भाषाओं में काम करने योग्य है। गतिशील रूप से टाइप की गई भाषाओं को या तो समय-यात्रा या कुछ चालाक विचारों की आवश्यकता होगी।

9

अस्पष्टता से बचने के लिए।

a(int) 
a(bool) 
int b() 
bool b() 

a(b()) -- Which b? 

यहां टाइप अनुमान में चक्रीय निर्भरता है। कौन सा ba पर निर्भर करता है, लेकिन कौन सा ab पर निर्भर करता है, इसलिए यह अटक जाता है।

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

+1

+1। –

+1

+1 टाइपिंग अनुमान के लिए +1 –

+0

कई संदिग्ध परिस्थितियां हैं, लेकिन इसका मतलब यह नहीं होगा कि ओवरलोडिंग उपयोगी नहीं हो सकती है अगर (1) कुछ "प्राथमिक" फ़ंक्शन का उपयोग किया जाना चाहिए, ऐसे मामलों को छोड़कर जहां कोई स्पष्ट रूप से बेहतर था, और (2) ऐसे मामलों में जो अभी भी संदिग्ध होंगे, एक कंपाइलर या तो उपयोग कर सकता है। कार्यों पर विचार करें (int32, int32) -> int32, (int32, int32) -> int64, और (int64, int64) -> int64। यदि वे उन मामलों में अर्थात् समान रूप से व्यवहार करते हैं जहां गणना मूल्य int32 के भीतर होता है, तो एक कंपाइलर (int64, int64) -> int64 हमेशा उपयोग कर सकता है, लेकिन प्रदर्शन बेहतर हो सकता है यदि (int32, int32) -> int32 का उपयोग किया गया था। – supercat

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

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