In Go language, sometimes it is necessary to delay processing a certain method, function or parameter, then the defer keyword is needed.
The effect of defer delay
1. Delay function
- You can add multiple defer statements in the function.
1) When the function is executed to the end, these defer statements will be executed in reverse order, and finally the function returns. Especially when you are doing some operations to open resources, you need to return in advance if you encounter errors. You need to close the corresponding resources before returning, otherwise it is easy to cause resource leakage and other problems;
2) If there are many calls to defer, Then defer adopts the last-in-first-out mode;
3) When leaving the method, execute defer itself (it will also execute when an error is reported)
Case 1. In the main function of the delay call a function
//myDeferFuc.go support func A delay in main () in ()
// myDeferDes project main.go
package main
import (
"fmt"
)
func funA() {
fmt.Println("我是funA()...")
}
func funB() {
fmt.Println("我是funB()...")
}
func funC() {
fmt.Println("我是funC()...")
}
func main() {
defer funA()
funB()
funC()
fmt.Println("main is over...")
}
The effect is as follows:
Case 2. Functions delay call a function
//myDeferFunc2.go delay in the implementation of func finished in Functions ()
// myDeferMax project main.go
package main
import (
"fmt"
)
func finished() {
fmt.Println("结束!")
}
func largest(s []int) {
defer finished()
fmt.Println("开始寻找最大数...")
max := s[0]
for _, v := range s {
if v > max {
max = v
}
}
fmt.Printf("%v中的最大数为:%v\n", s, max)
}
func main() {
s1 := []int{78, 109, 2, 563, 300}
largest(s1)
}
The effect is as follows:
Second, the delay method
- You can use defer to delay the call of a method
Case 3. Delay calling a method in the main function
//myDeferMethod.go
// myDeferMethod project main.go
package main
import (
"fmt"
)
type person struct {
firstName string
lastName string
}
func (per person) fullName() {
fmt.Printf("%s %s\n", per.firstName, per.lastName)
}
func main() {
per := person{"Steven", "Wang"}
defer per.fullName()
fmt.Printf("Welcome, ")
}
The effect is as follows:
Three, delay parameter transfer (retain parameters)
- Defer will retain the parameters before its declaration, and will execute at the end of the function.
Case 4. Keep parameters a and b, use defer
//myDeferMethod.go
// myDeferParam project main.go
package main
import (
"fmt"
)
func printAdd(a, b int) {
fmt.Printf("延迟函数中: 参数a,b分别为%d,%d, 两数之和为:%d\n", a, b, a+b)
}
func main() {
a := 5
b := 6
defer printAdd(a, b) //延迟参数a,b的传递
a = 10
b = 7
fmt.Printf("延迟函数执行前: 参数a,b分别为%d,%d, 两数之和为:%d\n", a, b, a+b)
}
The effect is as follows:
Fourth, the delay of the stack
- When a function has multiple delayed calls, they are added to a stack and executed in Last In First Out (LIFO) order.
Case 5. Using defer to achieve string reverse order
//myDeferReveser.go
// myDeferHeap project main.go
package main
import (
"fmt"
)
func ReverseString(str string) {
for _, v := range []rune(str) {
defer fmt.Printf("%c", v)
}
}
func main() {
name := "StevenWang欢迎学习区块链"
fmt.Println("原始字符串: ", name)
fmt.Println("翻转后的字符串: ")
ReverseString(name)
}
The effect is as follows:
Five, delay an application
- Recommend to use WaitGroup
Case 6 Delay an application
//myDeferApp.go
// myDeferApp project main.go
package main
import (
"fmt"
"sync"
)
type rect struct {
length int
width int
}
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)
}
func main() {
var wg sync.WaitGroup
r1 := rect{-67, 89}
r2 := rect{5, -67}
r3 := rect{8, 9}
rects := []rect{r1, r2, r3}
for _, v := range rects {
wg.Add(1)
go v.area(&wg)
}
wg.Wait()
fmt.Println("All go routines finished executing")
}
The effect is as follows: