ప్రధాన కంటెంట్‌కు వెళ్లండి
మాడ్యూల్ 3 · 5లో పాఠం 5కోర్సులో 15/50~12 min
మాడ్యూల్ పాఠాలు (5/5)

`డిఫర్`: హామీ క్లీనప్

defer కాల్ అమలును ** ఎన్‌క్లోజింగ్ ఫంక్షన్ వరకు వాయిదా వేస్తుంది తిరిగి**. పానిక్ ద్వారా ఫంక్షన్ నిష్క్రమించినా కూడా ఇది నడుస్తుంది. బహుళ defers అదే ఫంక్షన్‌లో LIFO క్రమంలో అమలు చేయండి (లాస్ట్-ఇన్, ఫస్ట్-అవుట్).

ఇది రిసోర్స్ క్లీనప్ కోసం ఇడియోమాటిక్ మెకానిజం: ఫైళ్లను మూసివేయడం, మ్యూటెక్స్‌లను అన్‌లాక్ చేయడం, కనెక్షన్‌లను విడుదల చేయడం, స్థితిని పునరుద్ధరించడం.

సింటాక్స్ మరియు కానానికల్ యూజ్ కేస్

Go
f, err := os.Open(path)
if err != nil {
    return err
}
defer f.Close()   // chiamata SEMPRE all'uscita della funzione

// ... usa f liberamente ...
return nil

సాధారణం: f.Close(), mu.Unlock(), db.Close(), tx.Rollback(), recover().

వాదనలు వెంటనే మూల్యాంకనం చేయబడ్డాయి, అమలు వాయిదా వేయబడింది

మీరు defer foo(x) అని వ్రాసినప్పుడు, x ఆ సమయంలో మూల్యాంకనం చేయబడుతుంది defer, అమలు సమయంలో కాదు:

Go
x := 10
defer fmt.Println(x)   // cattura 10
x = 99
// quando la funzione ritorna stampa "10", non "99"

LIFO ఆర్డర్

ఇటీవలి వాటితో ప్రారంభించి స్టాక్ అప్ మరియు ఎగ్జిక్యూట్‌ను వాయిదా వేస్తుంది:

Go
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
// output: 3, 2, 1

ఇది రిసోర్స్ సెమాంటిక్స్కు అనుగుణంగా ఉంటుంది: చివరిగా తెరవబడినది మొదటిది మూసివేయాలి.

defer + recover: భయాందోళనలను నిర్వహించడం

defer ఒక panicని అడ్డగించడానికి ఏకైక మార్గం:

Go
func safe() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("recuperato:", r)
        }
    }()
    panic("boom")
}

ఆపద: defer లూప్‌లో

defer f.Close()ని లూప్‌లో ఉంచడం వలన డిఫర్‌లు ** చివరి వరకు పేరుకుపోతాయి ఫంక్షన్**, ప్రతి పునరావృతం కాదు. సుదీర్ఘ లూప్‌లో మీరు చాలా ఫైల్‌లను తెరుస్తారు మరియు ఫంక్షన్ నిష్క్రమించినప్పుడు మాత్రమే వాటిని మూసివేయండి: ఫైల్ డిస్క్రిప్టర్ లీక్ ప్రమాదం.

Go
// MALE: defer accumulati
for _, path := range paths {
    f, _ := os.Open(path)
    defer f.Close()   // chiude TUTTI alla fine della funzione esterna
    // ...
}

// MEGLIO: estrai in una funzione
for _, path := range paths {
    elabora(path)   // ogni chiamata ha il proprio scope di defer
}

దీనిని ప్రయత్నించండి

వ్యాయామం#go.m3.l5.e1
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

'inizio'ని ప్రింట్ చేయండి, ఆపై 'ఫైన్' ప్రింట్‌ను డిఫర్‌తో వాయిదా వేయండి, ఆపై 'mezzo'ని ప్రింట్ చేయండి. అవుట్‌పుట్ తప్పనిసరిగా ఉండాలి: inizio / mezzo / fine.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

ప్రధాన() తిరిగి రాబోతున్నప్పుడు వాయిదా అమలవుతుంది.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

వ్యాయామం#go.m3.l5.e2
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

కోడ్‌లో ఆ క్రమంలో 1, 2 మరియు 3లను ప్రింట్ చేసే మూడు వరుస వాయిదాలను వ్రాయండి. అవుట్‌పుట్ 3/2/1 (LIFO)గా ఉంటుంది.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

క్రమంలో మూడు వాయిదాలు; వారు రివర్స్ క్రమంలో అమలు చేస్తారని గుర్తుంచుకోండి.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

Quiz#go.m3.l5.e3
సిద్ధంగా ఉంది

ఇది ఏమి ముద్రిస్తుంది? (గమనిక: వాయిదా వాదనలు వెంటనే మూల్యాంకనం చేయబడతాయి)

Go
x := 10
defer fmt.Println(x)
x = 99
సమాధాన ఎంపికలు

రీక్యాప్

  • defer call() ఫంక్షన్ తిరిగి వచ్చే వరకు అమలును వాయిదా వేస్తుంది.
  • బహుళ వాయిదాలు = LIFO ఆర్డర్.
  • వాదనలు వెంటనే మూల్యాంకనం చేయబడ్డాయి, అమలు వాయిదా వేయబడింది.
  • నిర్ణయాత్మక క్లీనప్ కోసం ఉపయోగించబడుతుంది: ఫైల్‌లు, మ్యూటెక్స్‌లు, కనెక్షన్‌లు.
  • defer + recover() ఒక panic (అరుదైనది, సరిహద్దుల వద్ద) అడ్డుకుంటుంది.
  • లాంగ్ లూప్ లోపల ఎప్పుడూ defer: బాహ్య ఫంక్షన్ తిరిగి వచ్చే వరకు ఇది పేరుకుపోతుంది.