Using Delay in Golang

What is the use deferin golang? The language documentation says that it runs when the surrounding function returns. Why not just put the code at the end of this function?

+26
source share
7 answers

Usually we use deferto close or free resources.

The surrounding function makes all pending function calls before returning, even if it panics. If you simply put a function call at the end of the surrounding function, it is skipped when panic occurs.

Moreover, a deferred function call can cope with panic by calling a built-in function recover. This cannot be done by a normal function call at the end of a function.

, . .

defer .

try-catch-finally.

try-finally:

func main() {
    f, err := os.Create("file")
    if err != nil {
        panic("cannot create file")
    }
    defer f.Close()
    // no matter what happens here file will be closed
    // for sake of simplicity I skip checking close result
    fmt.Fprintf(f,"hello")
}

try-catch-finally

func main() {
    defer func() {
        msg := recover()
        fmt.Println(msg)
    }()
    f, err := os.Create(".") // . is a current directory
    if err != nil {
        panic("cannot create file")
    }
    defer f.Close()
    // no matter what happens here file will be closed
    // for sake of simplicity I skip checking close result
    fmt.Fprintf(f,"hello")
}

try-catch-finally . .

finally, , .

func yes() (text string) {
    defer func() {
       text = "no"
    }()
    return "yes"
}

func main() {
    fmt.Println(yes())
}
+37

, , (, - ). defer , , , , .

defer esp. , esp . (, , ), , , . , , , , . , , close return). defer , , , , , , , .

. : , , , , , .

+4

defer - , , . , .

:

  1. panic. , try... catch .

  2. ( , ..) . - , . , . . - .

+2

. .

func BillCustomer(c *Customer) error {
    c.mutex.Lock()
    defer c.mutex.Unlock()

    if err := c.Bill(); err != nil {
        return err
    }

    if err := c.Notify(); err != nil {
        return err
    }

    // ... do more stuff ...

    return nil
}

defer , , BillCustomer, mutex unlocked BillCustomer. , defer , unlock mutex , return.

+2

defer .

defer :

func elapsed(what string) func() {
    start := time.Now()
    fmt.Println("start")
    return func() {
        fmt.Printf("%s took %v\n", what, time.Since(start))
    }
}

func main() {
    defer elapsed("page")()
    time.Sleep(time.Second * 3)
}

:

start
page took 3s
+1
  1. , . (, Golang , )
  2. A function can return at multiple points. User may skip some cleanup operations in some ways
  3. Some cleanup operations do not apply to all return paths.
  4. In addition, it is better to keep the cleanup code closer to the original operation that required cleanup.
  5. When we perform certain operations that require cleaning, we can “plan” the cleaning operations that will be performed when the function returns no matter which path occurs.
0
source

Source: https://habr.com/ru/post/1690170/


All Articles