En el lenguaje Go, a veces es necesario retrasar el procesamiento de un determinado método, función o parámetro, luego se necesita la palabra clave defer.
El efecto del retraso diferido
1. Función de retardo
- Puede agregar varias declaraciones diferidas en la función.
1) Cuando la función se ejecuta hasta el final, estas declaraciones diferidas se ejecutarán en orden inverso y finalmente la función regresa. Especialmente cuando está realizando algunas operaciones para abrir recursos, debe regresar con anticipación si encuentra errores. Debe cerrar los recursos correspondientes antes de regresar, de lo contrario es fácil causar fugas de recursos y otros problemas;
2) Si hay muchas llamadas para aplazar, Luego, diferir adopta el modo último en
entrar, primero en salir ; 3) Al salir del método, ejecutar diferir en sí mismo (también se ejecutará cuando se informe de un error)
Caso 1. En la función principal del retardo, llame a una función
//myDeferFuc.go support func Un retardo en 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...")
}
El efecto es el siguiente:
Caso 2. Retraso de funciones para llamar a una función
//myDeferFunc2.go retraso en la implementación de la función finalizada en Funciones ()
// 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)
}
El efecto es el siguiente:
En segundo lugar, el método de demora
- Puede utilizar aplazar para retrasar la llamada de un método
Caso 3. Retraso de llamar a un método en la función principal
//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, ")
}
El efecto es el siguiente:
Tres, retrasa la transferencia de parámetros (conserva los parámetros)
- Defer conservará los parámetros antes de su declaración y se ejecutará al final de la función.
Caso 4. Mantenga los parámetros ayb, 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)
}
El efecto es el siguiente:
Cuarto, el retraso de la pila.
- Cuando una función tiene varias llamadas retrasadas, se agregan a una pila y se ejecutan en el orden Último en entrar, primero en salir (LIFO).
Caso 5. Usar diferir para lograr el orden inverso de la cadena
//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)
}
El efecto es el siguiente:
Cinco, retrasa una solicitud
- Recomendar usar WaitGroup
Caso 6
Retrasar una solicitud //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")
}
El efecto es el siguiente: