2012-05-21 38 views
17

यह मुझे बहुत उलझन में मिला है और मुझे इस प्रश्न का उत्तर नहीं मिल रहा है। एक स्पष्ट और सरल स्पष्टीकरण अच्छा होगा।बंद पैरामीटर और 'उपयोग' कीवर्ड के बीच क्या अंतर है?

+0

मुझे लगता है कि आपने गलत जवाब चुना है – Trix

उत्तर

19

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

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

$string = "Hello World!"; 
$closure = function() use ($string) { echo $string; }; 

यह है जब आप एक समारोह क्या कहीं और कॉलबैक के रूप में इस्तेमाल किया जाना चाहिए बनाने की जरूरत के लिए उपयोगी है, और केवल मानकों को परिभाषित किया है सकते हैं। उपयोग() कीवर्ड चलो आप फ़ंक्शन बहस के रूप में पास किए गए लोगों के अलावा अन्य चर का उपयोग करते हैं। php.net उदाहरण पर उदाहरण के लिए: http://php.net/manual/en/functions.anonymous.php

public function getTotal($tax) 
    { 
     $total = 0.00; 

     $callback = 
      function ($quantity, $product) use ($tax, &$total) 
      { 
       $pricePerItem = constant(__CLASS__ . "::PRICE_" . 
        strtoupper($product)); 
       $total += ($pricePerItem * $quantity) * ($tax + 1.0); 
      }; 

     array_walk($this->products, $callback); 
     return round($total, 2); 
    } 

$ कॉलबैक केवल दो पैरामीटर होना आवश्यक है, क्योंकि array_walk केवल इतना अनुमति देगा:

आमतौर पर, funcname दो मापदंडों पर ले जाता है। सरणी पैरामीटर का मान पहला होता है, और कुंजी/अनुक्रमणिका दूसरा होता है।

तो हम क्या कर सकते हैं? हम use() फोन अन्य चर है कि $ कॉलबैक की गुंजाइश नहीं हैं जोड़ने के लिए है, लेकिन पर्यावरण के दायरे में यह कहा जाता है में जा रहा है।

+0

यह अभी भी मुझे समझ में नहीं आता है। यह '$ बंद = फ़ंक्शन ($ स्ट्रिंग) {echo $ string से अलग कैसे है; }; '? – Seralize

+1

@Seralize: क्षमा करें, मेरा उदाहरण अपडेट किया गया। असल में, PHP में कुछ फ़ंक्शन कॉलबैक (जैसे array_walk, array_map, आदि) को पूर्वनिर्धारित पैरामीटर की अनुमति देते हैं। इन उदाहरणों में, आप अन्य चर जोड़ने के लिए उपयोग() को कॉल कर सकते हैं, अन्यथा कॉलबैक में उपयोग करना संभव नहीं होगा। –

+0

यह समझ में आता है तो 'उपयोग() 'कीवर्ड मूल रूप से" पैरामीटर प्रवाह "को गड़बड़ किए बिना चर में चर आयात करने का एक तरीका है, क्योंकि सेट नहीं किए गए पैरामीटर में कोई त्रुटि होगी? – Seralize

24

use statement समय बंद समारोह बनाई गई है पर कब्जा चर

नियमित फ़ंक्शन तर्क मान पर कब्जा करते हैं जब फ़ंक्शन कहा जाता है।

ध्यान दें कि मैंने variable और value के बीच अंतर किया है।

function makeAnAdder($leftNum) { 
    // Notice that *each time* this makeAnAdder function gets called, we 
    // create and then return a brand new closure function. 
    $closureFunc = function($rightNum) use ($leftNum) { 
     return $leftNum + $rightNum; 
    }; 

    return $closureFunc; 
} 

$add5to = makeAnAdder(5); 
$add7to = makeAnAdder(7); 

echo $add5to(10); // 15 
echo $add7to(1); // 8 

अगर वहाँ $add5to समारोह के "स्रोत कोड" का निरीक्षण करने, उम, एक तरह से थे, यह इस प्रकार दिखाई देगा:

function($rightNum) { 
    return 5 + $rightNum; 
} 

मुझे लगता है कि आप थोड़े $leftNum का मूल्य कह सकते हैं बंद समारोह द्वारा याद किया गया।

मैं आगे जोर देना कि use statement आप एक चर करने के लिए एक reference, और न सिर्फ मूल्य कि चर कुछ बिंदु पर था की एक प्रति बनाए रखने के लिए अनुमति देता है चाहता हूँ। मेरे विचार को स्पष्ट करने के लिए: एक चर के बारे में एक छोटे बॉक्स के रूप में सोचें, जिसमें किसी भी समय एक ही मूल्य हो सकता है, और वह मान बदला जा सकता है।और, आप उस बॉक्स में एक और चर बिंदु बना सकते हैं, ताकि आप बॉक्स में मान अपडेट कर सकें या इसमें वर्तमान मान पढ़ सकें।

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

यहां एक और उन्नत उदाहरण है, जो व्यवहार के बढ़िया विवरण को समझने के लिए कुछ गहरी सोच ले सकता है।

function makeBankAccount() { 
    // Each time this makeBankAccount func is called, a new, totally 
    // independent local variable named $balance is created. 
    $balance = 0; 

    // Also, on each call we create 2 new closure functions, $modifyBalance, and $getBalance 
    // which will hold a reference to the $balance variable even after makeBankAccount returns. 
    $modifyBalance = function($amount) use (&$balance) { 
     $balance += $amount; 
    }; 

    $getBalance = function() use (&$balance) { 
     return $balance; 
    }; 

    // return both closure functions. 
    return ['modifyBalance' => $modifyBalance, 'getBalance' => $getBalance]; 
} 

// Let's prove that bank1 works by adding 5 to the balance by using the first 
// function, then using the other function to get the balance 
// from the same internal variable. 
$bank1 = makeBankAccount(); 
$bank1['modifyBalance'](5); 
echo $bank1['getBalance'](); // 5 - it works. 

// Now let's make another bank to prove that it has it's own independent internal $balance variable. 
$bank2 = makeBankAccount(); 
$bank2['modifyBalance'](10); 
echo $bank2['getBalance'](); // 10 - as expected. It would have printed 15 if bank2 shared a variable with bank1. 

// Let's test bank1 one more time to be sure that bank2 didn't mess with it. 
echo $bank1['getBalance'](); // 5 - still 5, as expected. 

आपने ध्यान दिया होगा कि मैं इस उदाहरण में reference operator& इस्तेमाल किया। यदि आप अभी तक उनके साथ अभी तक परिचित नहीं हैं, तो बस यह जान लें कि संदर्भ समझने के लिए कठिन हैं। हालांकि, मुझे आशा है कि यह पोस्ट ज्यादातर स्वयं ही समझ में आता है।

+0

यह एक अच्छा बिंदु है जो आप वहां पहुंचे। मुझे समझने में थोड़ी देर लग गई कि '$ राइटनम' पैरामीटर कैसे बुलाया गया लेकिन अब यह समझ में आता है। – Seralize

+0

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

+2

यह उत्तर स्वीकार्य उत्तर होने के योग्य है – Trix

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