Na linguagem Go, às vezes é necessário atrasar o processamento de um determinado método, função ou parâmetro, então a palavra-chave defer é necessária.
O efeito do atraso de adiamento
1. Função de atraso
- Você pode adicionar várias instruções defer na função.
1) Quando a função é executada até o fim, essas instruções defer serão executadas na ordem reversa e, finalmente, a função retorna. Especialmente quando você está fazendo algumas operações para abrir recursos, você precisa retornar com antecedência se encontrar erros. Você precisa fechar os recursos correspondentes antes de retornar, caso contrário, é fácil causar vazamento de recursos e outros problemas;
2) Se houver muitas chamadas para adiar, Em seguida, adiar adota o modo last-in-first-out ;
3) Ao sair do método, execute o adiamento (ele também será executado quando um erro for relatado)
Caso 1. Na função principal do atraso, chame uma função
//myDeferFuc.go support func Um atraso em main () em ()
// 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...")
}
O efeito é o seguinte:
![](https://img-blog.csdnimg.cn/20201003150125545.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NhbnFpbWE=,size_16,color_FFFFFF,t_70#pic_center)
Caso 2. Atraso de funções chama uma função
//myDeferFunc2.go atraso na implementação de função concluída em 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)
}
O efeito é o seguinte:
![](https://img-blog.csdnimg.cn/20201003150732951.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NhbnFpbWE=,size_16,color_FFFFFF,t_70#pic_center)
Em segundo lugar, o método de atraso
- Você pode usar adiar para atrasar a chamada de um método
Caso 3. Atraso na chamada de um método na função 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, ")
}
O efeito é o seguinte:
![](https://img-blog.csdnimg.cn/20201003151127360.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NhbnFpbWE=,size_16,color_FFFFFF,t_70#pic_center)
Três, atrasar a transferência dos parâmetros (reter os parâmetros)
- O adiar reterá os parâmetros antes de sua declaração e será executado no final da função.
Caso 4. Mantenha os parâmetros aeb, 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)
}
O efeito é o seguinte:
![](https://img-blog.csdnimg.cn/20201003152222821.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NhbnFpbWE=,size_16,color_FFFFFF,t_70#pic_center)
Quarto, o atraso da pilha
- Quando uma função tem várias chamadas atrasadas, elas são adicionadas a uma pilha e executadas na ordem Last In First Out (LIFO).
Caso 5. Usando adiar para obter a ordem reversa da string
//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)
}
O efeito é o seguinte:
![](https://img-blog.csdnimg.cn/20201003152733428.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NhbnFpbWE=,size_16,color_FFFFFF,t_70#pic_center)
Cinco, atrasar uma aplicação
- Recomende usar WaitGroup
Caso 6 Atrasar um aplicativo
//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")
}
O efeito é o seguinte:
![](https://img-blog.csdnimg.cn/20201003153140783.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NhbnFpbWE=,size_16,color_FFFFFF,t_70#pic_center)