खोज…
बंद मूल बातें
क्लोजर एक फंक्शन है जिसे एक पर्यावरण के साथ लिया जाता है। फ़ंक्शन आमतौर पर एक अन्य फ़ंक्शन के अंदर परिभाषित एक अनाम फ़ंक्शन है। पर्यावरण एन्कोडिंग फ़ंक्शन का लेक्सिकल स्कोप है (फ़ंक्शन के लेक्सिकल स्कोप का बहुत मूल विचार कार्यक्षेत्र के ब्रेसिज़ के बीच मौजूद स्कोप होगा।)
func g() {
i := 0
f := func() { // anonymous function
fmt.Println("f called")
}
}
एक अन्य फ़ंक्शन (मान g
) के भीतर परिभाषित एक अनाम फ़ंक्शन (मान f
) के शरीर के भीतर, f
और g
दोनों के स्कोप में मौजूद चर सुलभ होते हैं। हालाँकि, यह g
का दायरा है जो क्लोजर के पर्यावरण भाग (फंक्शन पार्ट f
) का निर्माण करता है और इसके परिणामस्वरूप, g
के स्कोप में वैरिएबल में किए गए परिवर्तन उनके मान को बनाए रखते हैं (यानी पर्यावरण कॉल के बीच बनी रहती है f
) ।
नीचे दिए गए कार्य पर विचार करें:
func NaturalNumbers() func() int {
i := 0
f:= func() int { // f is the function part of closure
i++
return i
}
return f
}
उपरोक्त परिभाषा में, NaturalNumbers
में एक आंतरिक फ़ंक्शन f
जो NaturalNumbers
रिटर्न करता है। अंदर f
, चर i
के दायरे के भीतर परिभाषित NaturalNumbers
पहुँचा जा रहा है।
हमें NaturalNumbers
से एक नया फ़ंक्शन मिलता है:
n := NaturalNumbers()
अब n
एक बंद है। यह एक फ़ंक्शन ( f
द्वारा परिभाषित) है जिसमें एक संबद्ध वातावरण ( NaturalNumbers
दायरा) भी है।
n
मामले में, पर्यावरण भाग में केवल एक चर होता है: i
चूंकि n
एक फ़ंक्शन है, इसलिए इसे कहा जा सकता है:
fmt.Println(n()) // 1
fmt.Println(n()) // 2
fmt.Println(n()) // 3
जैसा कि उपरोक्त आउटपुट से स्पष्ट है, हर बार n
को बुलाया जाता है, यह वृद्धि करता है i
। i
0 से शुरू होता है, और प्रत्येक कॉल n
i++
निष्पादित करता है।
कॉल के बीच i
का मान बरकरार है। यही है, पर्यावरण, बंद होने का एक हिस्सा है, बनी रहती है।
नेचुरल NaturalNumbers
फिर से कॉल करने से एक नया फंक्शन होगा और वापस आएगा। यह NaturalNumbers
भीतर एक नया i
इनिशियलाइज़ करेगा। जिसका अर्थ है कि नव लौटा हुआ फ़ंक्शन फ़ंक्शन के लिए एक ही भाग वाले एक अन्य क्लोजर बनाता है (अभी भी f
) लेकिन एक नया वातावरण (एक नया प्रारंभिक i
)।
o := NaturalNumbers()
fmt.Println(n()) // 4
fmt.Println(o()) // 1
fmt.Println(o()) // 2
fmt.Println(n()) // 5
n
और o
दोनों एक ही कार्य भाग वाले क्लोजर हैं (जो उन्हें समान व्यवहार देता है), लेकिन विभिन्न वातावरण। इस प्रकार, क्लोजर के उपयोग से फ़ंक्शंस को लगातार वातावरण तक पहुंच प्राप्त करने की अनुमति मिलती है जिसका उपयोग कॉल के बीच जानकारी बनाए रखने के लिए किया जा सकता है।
एक और उदाहरण:
func multiples(i int) func() int {
var x int = 0
return func() int {
x++
// paramenter to multiples (here it is i) also forms
// a part of the environment, and is retained
return x * i
}
}
two := multiples(2)
fmt.Println(two(), two(), two()) // 2 4 6
fortyTwo := multiples(42)
fmt.Println(fortyTwo(), fortyTwo(), fortyTwo()) // 42 84 126