खोज…


परिचय

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

वाक्य - विन्यास

  • कुछ का बचाव करें (args)
  • defer func () {// कोड यहाँ जाता है} ()

टिप्पणियों

वर्तमान में निष्पादित फ़ंक्शन के नीचे कॉल स्टैक में एक नया स्टैक फ्रेम ( defer कीवर्ड के बाद का फ़ंक्शन) कहा जाता है। इसका मतलब यह है कि जब तक स्टैक SIGKILL हो जाएगा (जब तक कि आपका प्रोग्राम क्रैश हो जाता है या SIGKILL हो जाता है, तो SIGKILL नहीं करेगा) को स्थगित करने की गारंटी दी जाती है।

डेफर बेसिक्स

गो में एक डीफर स्टेटमेंट केवल एक फ़ंक्शन कॉल है जिसे बाद के समय में निष्पादित किया जाना है। आस्थगित करें बयान एक साधारण समारोह कॉल कीवर्ड लगाया जाता है defer

defer someFunction()

एक आस्थगित फ़ंक्शन को एक बार फ़ंक्शन निष्पादित किया जाता है जिसमें defer स्टेटमेंट रिटर्न होता है। आस्थगित फ़ंक्शन के लिए वास्तविक कॉल तब होता है जब एन्कोडिंग फ़ंक्शन:

  • रिटर्न स्टेटमेंट निष्पादित करता है
  • अंत तक गिर जाता है
  • घबरा

उदाहरण:

func main() {
    fmt.Println("First main statement")
    defer logExit("main") // position of defer statement here does not matter
    fmt.Println("Last main statement")
}

func logExit(name string) {
    fmt.Printf("Function %s returned\n", name)
}

आउटपुट:

First main statement
Last main statement
Function main returned

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

func main() {
    defer logNum(1)
    fmt.Println("First main statement")
    defer logNum(2)
    defer logNum(3)
    panic("panic occurred")
    fmt.Println("Last main statement") // not printed
    defer logNum(3) // not deferred since execution flow never reaches this line
}

func logNum(i int) {
    fmt.Printf("Num %d\n", i)
}

आउटपुट:

First main statement
Num 3
Num 2
Num 1
panic: panic occurred

goroutine 1 [running]:
....

ध्यान दें कि आस्थगित कार्यों के समय तर्क को निष्पादित defer उनके तर्क का मूल्यांकन किया जाता है:

func main() {
    i := 1
    defer logNum(i) // deferred function call: logNum(1)
    fmt.Println("First main statement")
    i++
    defer logNum(i) // deferred function call: logNum(2)
    defer logNum(i*i) // deferred function call: logNum(4)
    return // explicit return
}

func logNum(i int) {
    fmt.Printf("Num %d\n", i)
}

आउटपुट:

First main statement
Num 4
Num 2
Num 1

यदि किसी फ़ंक्शन ने रिटर्न मान का नाम दिया है, तो फ़ंक्शन के भीतर एक स्थगित अनाम फ़ंक्शन फ़ंक्शन के वापस आने के बाद भी दिए गए मान को एक्सेस और अपडेट कर सकता है:

func main() {
    fmt.Println(plusOne(1)) // 2
    return
}

func plusOne(i int) (result int) { // overkill! only for demonstration
    defer func() {result += 1}() // anonymous function must be called by adding ()

    // i is returned as result, which is updated by deferred function above
    // after execution of below return
    return i
}

अंत में, एक defer स्टेटमेंट का आमतौर पर उपयोग किए जाने वाले ऑपरेशन होते हैं जो अक्सर एक साथ होते हैं। उदाहरण के लिए:

  • किसी फ़ाइल को खोलें और बंद करें
  • कनेक्ट करें और डिस्कनेक्ट करें
  • म्यूटेक्स को लॉक और अनलॉक करें
  • के रूप में किया एक वेटग्रुप को चिह्नित करें ( defer wg.Done() )

यह उपयोग निष्पादन के प्रवाह के बावजूद सिस्टम संसाधनों की उचित रिहाई सुनिश्चित करता है।

resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close() // Body will always get closed

आस्थगित समारोह कॉल

आस्थगित फ़ंक्शन कॉल जावा जैसी भाषाओं में finally ब्लॉक जैसी चीजों के लिए एक समान उद्देश्य की सेवा करते हैं: वे यह सुनिश्चित करते हैं कि जब कोई त्रुटि हुई या जो रिटर्न स्टेटमेंट कई रिटर्न वाले मामलों में हिट हुई थी, भले ही बाहरी फ़ंक्शन वापस आए, तो कुछ फ़ंक्शन निष्पादित किए जाएंगे। यह उन संसाधनों की सफाई के लिए उपयोगी है जिन्हें नेटवर्क कनेक्शन या फ़ाइल पॉइंटर्स की तरह बंद किया जाना चाहिए। defer कीवर्ड इसी तरह करने के लिए, एक आस्थगित समारोह कॉल इंगित करता है go कीवर्ड एक नई goroutine की शुरुआत। एक go कॉल की तरह, फ़ंक्शन तर्कों का तुरंत मूल्यांकन किया जाता है, लेकिन एक go कॉल के विपरीत, स्थगित कार्यों को समवर्ती रूप से निष्पादित नहीं किया जाता है।

func MyFunc() {
    conn := GetConnection()    // Some kind of connection that must be closed.
    defer conn.Close()        // Will be executed when MyFunc returns, regardless of how.
    // Do some things...
    if someCondition {
        return                // conn.Close() will be called
    }
    // Do more things
}// Implicit return - conn.Close() will still be called

conn.Close() बजाय conn.Close() के उपयोग पर ध्यान दें - आप केवल एक फ़ंक्शन में नहीं गुजर रहे हैं, आप अपने तर्क सहित एक पूर्ण फ़ंक्शन कॉल को conn.Close कर रहे हैं। एक से अधिक फ़ंक्शन कॉल को एक ही बाहरी फ़ंक्शन में स्थगित किया जा सकता है, और प्रत्येक को एक बार रिवर्स ऑर्डर में निष्पादित किया जाएगा। आप क्लोजर को भी टाल सकते हैं - सिर्फ परनों को मत भूलना!

defer func(){
    // Do some cleanup
}()


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow