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.