2010-09-22 12 views

उत्तर

47

नेस्टेड फ़ंक्शंस को अनदेखा करना, रिटर्न के बिना बराबर गणना के साथ रिला के साथ स्कैला गणनाओं को प्रतिस्थापित करना हमेशा संभव है। यह परिणाम "संरचित प्रोग्रामिंग" के शुरुआती दिनों में वापस जाता है, और इसे structured program theorem कहा जाता है, जो चतुराई से पर्याप्त है।

नेस्टेड कार्यों के साथ, स्थिति बदलती है। स्कैला आपको नेस्टेड फ़ंक्शंस की श्रृंखला के अंदर गहरी दफन करने की अनुमति देता है। जब रिटर्न निष्पादित किया जाता है, तो सभी नेस्टेड फ़ंक्शंस से बाहर निकलता है, जिसमें अंतर्निहित विधि होती है, जिसमें से यह लौटाता है (माना जाता है कि विधि वास्तव में अभी भी निष्पादित है, अन्यथा अपवाद फेंक दिया गया है)। इस तरह के स्टैक-अवांछित अपवादों के साथ किया जा सकता है, लेकिन गणना के यांत्रिक पुनर्गठन के माध्यम से नहीं किया जा सकता है (जैसा कि नेस्टेड कार्यों के बिना संभव है)।

सबसे आम कारण है कि आप वास्तव में एक नेस्टेड फ़ंक्शन के अंदर से वापस लौटना चाहते हैं, एक अनिवार्य समझ-समझ या संसाधन नियंत्रण ब्लॉक से बाहर निकलना है। (एक अनिवार्य के लिए-समझ के शरीर एक नेस्टेड समारोह में अनुवाद किया जाता है, भले ही यह सिर्फ एक बयान की तरह दिखता है।)

for(i<- 1 to bezillion; j <- i to bezillion+6){ 
if(expensiveCalculation(i, j)){ 
    return otherExpensiveCalculation(i, j) 
} 

withExpensiveResource(urlForExpensiveResource){ resource => 
// do a bunch of stuff 
if(done) return 
//do a bunch of other stuff 
if(reallyDoneThisTime) return 
//final batch of stuff 
} 
+0

उत्तर के लिए धन्यवाद।यह बहुत जानकारीपूर्ण है। – Jus12

+0

मुझे लगता है कि यह एक अधिक औपचारिक उत्तर है। मुझे आपके द्वारा बताए गए नतीजे के सबूत में दिलचस्पी है। क्या आप कुछ संदर्भ प्रदान कर सकते हैं? – Jus12

+0

संरचित कार्यक्रम प्रमेय के लिए विकिपीडिया के लिए एक लिंक जोड़ा गया। –

26

यह उन परिस्थितियों को समायोजित करने के लिए प्रदान किया जाता है जिसमें विधि के व्याख्यात्मक अंत में अभिसरण करने के लिए सभी नियंत्रण प्रवाह पथों को व्यवस्थित करना कठिन या बोझिल होता है।

हालांकि यह निश्चित रूप से सच है, क्योंकि डेव ग्रिफिथ कहते हैं कि आप return के किसी भी उपयोग को खत्म कर सकते हैं, यह अक्सर return के साथ निष्पादन को कम करने के बजाय ऐसा करने के लिए अधिक अप्रिय हो सकता है।

जागरूक रहें, return विधियों से लौटाता है, कार्य (अक्षर) नहीं जो किसी विधि के भीतर परिभाषित किया जा सकता है।

+0

मुझे पता था कि यह जवाब था .. मैं बस किसी भी उदाहरण के बारे में नहीं सोच सकता। – Jus12

+8

सौभाग्य से मेरे लिए, आपने किसी भी उदाहरण के लिए नहीं पूछा ... –

+0

+1 obfuscatory –

2

मैं एक उपयोगी के रूप में return देखने जब जो आम तौर पर मैं इसका मतलब जरूरी शैली कोड, लेखन/हे कोड यदि आप शुद्ध कार्यात्मक कोड कर रहे हैं, तो आपको return की आवश्यकता नहीं है (और इसका उपयोग नहीं करना चाहिए)। लेकिन कार्यात्मक कोड के साथ आपको अनिवार्य कोड के बराबर प्रदर्शन प्राप्त करने के लिए आलस्य की आवश्यकता हो सकती है जो return का उपयोग करके "जल्दी से बचें" कर सकते हैं।

3

यहाँ, एक उदाहरण

इस विधि अगर-बाकी बयान प्रवाह को नियंत्रित करने के बहुत सारे है कोई वापसी न होने के कारण (है कि क्या मैं के साथ, आप अपनी कल्पना का उपयोग करें यह विस्तार करने के लिए कर सकते हैं आया है)। मैं एक वास्तविक जीवन उदाहरण से इस ले लिया और इसे संशोधित (वास्तव में यह इस से अधिक लंबी है) एक डमी कोड होने के लिए:

वापसी के बिना:

def process(request: Request[RawBuffer]): Result = { 
     if (condition1) { 
     error() 
     } else { 
     val condition2 = doSomethingElse() 
     if (!condition2) { 
      error() 
     } else { 
      val reply = doAnotherThing() 
      if (reply == null) { 
      Logger.warn("Receipt is null. Send bad request") 
      BadRequest("Coudln't receive receipt") 
      } else { 
      reply.hede = initializeHede() 
      if (reply.hede.isGood) { 
       success() 
      } else { 
       error() 
      } 
      } 
     } 
     } 
    } 

वापसी के साथ:

def process(request: Request[RawBuffer]): Result = { 
     if (condition1) { 
     return error() 
     } 

     val condition2 = doSomethingElse() 
     if (!condition2) { 
     return error() 
     } 

     val reply = doAnotherThing() 

     if (reply == null) { 
     Logger.warn("Receipt is null. Send bad request") 
     return BadRequest("Coudln't receive receipt") 
     } 

     reply.hede = initializeHede() 
     if (reply.hede.isGood) 
     return success() 

     return error() 
    } 

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

+2

मुझे लगता है कि अच्छी तरह से अनुभवी स्कैला प्रोग्रामर (मुझे नहीं) पहले स्निपेट का अधिक स्पष्ट रूप से अनुसरण कर सकते हैं। – Jus12

+0

वास्तव में यह 'स्वाद' का थोड़ा सा है, डेवलपर्स दृष्टिकोण पर निर्भर करता है। जैसे मुझे सबसे ज्यादा फ्लैट पसंद है – yerlilbilgin

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