2010-07-21 14 views
5

बंद होने और उसके पत्राचार उदाहरण क्या है?क्लोजर परिभाषा और उदाहरण

मैंने बहुत कुछ शोध किया है और समझ में नहीं आया। कृपया जेनेरिक प्रोग्रामिंग भाषा अवधारणा पहलू और विशिष्ट प्रोग्रामिंग भाषा पहलू में समझाएं।

कृपया मदद करें।

धन्यवाद।

function A() { 
    var x = 5; 

    function B() { 
     print(x); 
    } 

    return B; 
} 

आप एक सी ++ पृष्ठभूमि से आते हैं, तो यह नहीं बल्कि पचाने में मुश्किल है:

+0

प्रश्न http://stackoverflow.com/questions/36636/what-is-a-closure और http://stackoverflow.com/questions/1095707/what-is-the-exact-definition-of-a- बंद इस –

उत्तर

1

यहाँ है मैं कैसे एक बंद के बारे में सोच ....

एक समारोह वस्तु दो बातें शामिल हैं। पहली बात फ़ंक्शन के लिए कोड है, दूसरा वह दायरा है जिसमें यह निष्पादित होता है। एक बंद में, जिस दायरे में फ़ंक्शन निष्पादित होता है और कोड एक-दूसरे से अलग हो जाता है। एक ही कोड विभिन्न प्रकार के क्षेत्रों में निष्पादित कर सकता है।

यदि इसे पूरी तरह से अप्रतिबंधित तरीके से अनुमति दी गई तो इसका परिणाम बहुत भ्रमपूर्ण होगा। यहां तक ​​कि जब यह गतिशील स्कोपिंग के रूप में ढीला होता है (फ़ंक्शन उस स्थान के दायरे को प्राप्त करता है जहां से इसे कहा जाता था) यह बहुत भ्रमित हो जाता है।

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

def outer(): 
    def closure(): 
     pass 
    return closure 

यहाँ समारोह closure एक बंद है:

यहाँ पायथन में एक छोटी सी बंद का एक उदाहरण है। यह वास्तव में उस क्षेत्र से किसी भी चर का उपयोग नहीं करता है जिसमें इसे परिभाषित किया गया था, इसलिए यह बहुत छोटा है, लेकिन यह अभी भी एक है।

यहाँ पायथन में एक नहीं तो तुच्छ, लेकिन अभी भी सरल बंद है:

def outer(x): 
     def closure(): 
      return x 
     return closure 
f1 = outer(5) 
f2 = outer(6) 

कॉलिंग f1() वापस आ जाएगी 5 और f2() बुला 6. वापस आ जाएगी आप देख सकते हैं, समारोह closure हिस्सा कोड है , और भाग गुंजाइश।

जब outer(5) कहा जाता है, यह है कि मूल्य 5. पकड़े यह तो समारोह closure जो कि गुंजाइश हो जाता है वाणी चर x का एक संस्करण शामिल है कॉल के लिए एक ढेर प्रविष्टि बना देता है।

जब outer(6) कहा जाता है, यह है कि मूल्य 6. पकड़े यह तो समारोह closure जो कि गुंजाइश हो जाता है वाणी चर x का एक संस्करण शामिल है कॉल के लिए एक ढेर प्रविष्टि बना देता है।

+0

आपकी व्याख्या के लिए धन्यवाद – peterwkc

9

एक बंद मूल रूप से एक समारोह बी एक समारोह एक है कि एक के स्थानीय चर का उपयोग कर सकते अंदर नेस्टेड है। जब हम ए द्वारा लौटाए गए फ़ंक्शन को कॉल करने का प्रयास करते हैं, तो x क्या इसका उल्लेख होगा? A() समाप्त होने के बाद से अमान्य नहीं होगा?

उत्तर यह है कि x वास्तव में रहता है। वह B हम वास्तव में इसके साथ लगभग x लेते हैं। अच्छा, आह?

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

क्लोजर वास्तव में उपयोगी हैं। उदाहरण के लिए, मान लीजिए हम अपने "पाश के लिए" खुद लागू करना चाहते हैं:

function loop(count, f) { 
    for (var i = 0; i < count; i++) 
     f(i); 
} 

var array = [0,1,2,3,4]; 

loop(5, function(i) { 
    print(array[i]); 
}); 

अतिरिक्त बकवास का एक समूह ऐसा किए बिना बाहर चर का उपयोग करने की अनुमति दी जा रही कोड अच्छा और सरल रहता है। बंद के बिना, आप के बजाय loop कार्य करने के लिए एक संदर्भ चर पारित करने के लिए हो सकता है:

function loop(count, f, ctx) { 
    for (var i = 0; i < count; i++) 
     f(i, ctx); 
} 

var array = [0,1,2,3,4]; 

loop(5, function(i, ctx) { 
    print(ctx[i]); 
}, array); 

एक और उदाहरण: मान लीजिए हम jQuery में एक कॉलबैक पंजीकृत करना चाहते हैं, लेकिन यह लंबे समय तक समारोह और उसके फोन करने वाले के बाद क्रियान्वित किया जा सकता है और अपने फोन करने वाले का फोन करने वाले से चल रहा से किया जाता है:

$(document).ready(function(){ 

    var clicked = 0; 

    $('#button').click(function(){ 
     clicked++; 
     alert("You've pressed the button " + clicked + " times."); 
    }); 

}); 

तो जावास्क्रिप्ट गया अधिक सी की तरह ++ (C++ 0x से पहले), कि clicked चर लंबे समय से चला की जाएगी समारोह $(document).ready() करने के लिए दिया जाता था, और बटन पर क्लिक कॉलबैक में अपरिभाषित व्यवहार होगा।

+0

के समान हैं दिलचस्प बात यह है कि सी ++ 0x में अब लैम्ब्डा हैं जो उनके संलग्न क्षेत्र से चर को कैप्चर करते हैं। तो * "यदि आप सी ++ पृष्ठभूमि से आते हैं" * तर्क कम प्रासंगिक हो जाता है। –

+0

यह बहुत अच्छा है। धन्यवाद। – LandonSchropp

+0

@ एलेक्सेंड्रे जैस्मीन - वे बंद होने का एक बहुत ही अजीब रूप है। उन भाषाओं की तुलना में अधिक स्पष्ट है जो उन्हें समर्थन देते हैं। हालांकि मैं वास्तव में इस तरह से बेहतर पसंद करता हूं। मुझे लगता है कि आप __should__ को यह कहना है कि आप किस चर को संलग्नक क्षेत्र से उपयोग करना चाहते हैं। – Omnifarious

0

मैं तुम्हें अजगर में किताब की जांच करने के

गोता सुझाव है कि आप बंद पर एक उदाहरण चाहते हैं: अध्याय 6 - क्लोजर & जेनरेटर

पुस्तक अपनी खुली & मुक्त और आप इसे डाउनलोड कर सकते हैं --->http://diveintopython3.org/

उदाहरण यह दिलचस्प है, स्पष्ट और धीरे-धीरे एक और उन्नत दृष्टिकोण लेता है। पहली एक्सपोजर के लिए मुझे लगता है कि यह महान है।

इस पर एक नज़र डालें, इसे तब तक पुन: उत्पन्न करने का कोई कारण नहीं है जब तक कि आप इसे डाउनलोड या इसे ऑनलाइन पढ़ सकें।

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