Golang Study Notes delay function of defer usage Summary

  • 2020-06-23 00:36:01
  • OfStack

The defer is elegant and simple, which is one of the highlights of golang. defer does not execute immediately upon declaration, but after the function return, each defer is executed in sequence, following the first-in, first-out principle.

The keyword defer is invoked with deferred registration. These calls are not performed until ret and are usually used to free resources or error handling.

1. When defer is declared, its parameters are resolved in real time


func a() {
  i := 0
  defer fmt.Println(i) // The output 0 Because the i At this point is 0
  i++
  defer fmt.Println(i) // The output 1 Because the i At this point is 1
  return
}

2. When defer is called more than once within a function, Go places the defer call on a stack and then executes it in lifo order.


func main() {
  defer fmt.Println("1")
  defer fmt.Println("2")
  defer fmt.Println("3")
  defer fmt.Println("4")
}

The output order is 4321

Use defer to invert the output string


name := "Naveen hello "
  fmt.Printf("%s\n", string(name))
  fmt.Printf(" The reverse :")
  defer fmt.Printf("\n")
  for _, v := range []rune(name) {
    defer fmt.Printf("%c", v)
  }

Output:

[

Hi Naveen

In reverse order: Ok you neevaN

]

3. Practical application of defer


func (r rect) area(wg *sync.WaitGroup) {
  if r.length < 0 {
    fmt.Printf("rect %v's length should be greater than zero\n", r)
    wg.Done()
    return
  }
  if r.width < 0 {
    fmt.Printf("rect %v's width should be greater than zero\n", r)
    wg.Done()
    return
  }
  area := r.length * r.width
  fmt.Printf("rect %v's area %d\n", r, area)
  wg.Done()
}

We will see that wg.Done () above is called multiple times and we can use defer to optimize the code


func (r rect) area(wg *sync.WaitGroup) {
  defer wg.Done()
  if r.length < 0 {
    fmt.Printf("rect %v's length should be greater than zero\n", r)
    return
  }
  if r.width < 0 {
    fmt.Printf("rect %v's width should be greater than zero\n", r)
    return
  }
  area := r.length * r.width
  fmt.Printf("rect %v's area %d\n", r, area)
}

Delayed calls with defer are called before the end of the program

Here's an example:


package main 
import "fmt" 
func deferTest(number int) int {
 defer func() {
 number++
 fmt.Println("three:", number)
 }()
 
 defer func() {
 number++
 fmt.Println("two:", number)
 }()
 
 defer func() {
 number++
 fmt.Println("one:", number)
 }()
 
 return number
}
 
func main() {
 fmt.Println(" Function return value: ", deferTest(0))
}

The above code prints the following:

[

one: 1
two: 2
three: 3
Function return value: 0

]

PS: defer has one important feature that allows defer to be executed even if the function throws an exception. This will prevent the resource from being released because of an error in the program.


Related articles: