服务器之家

服务器之家 > 正文

Golang学习笔记之延迟函数(defer)的使用小结

时间:2020-05-21 10:51     来源/作者:学生黄哲

golang的defer优雅又简洁, 是golang的亮点之一。defer在声明时不会立即执行,而是在函数return后,再按照先进后出的原则依次执行每个defer,一般用于释放资源、清理数据、记录日志、异常处理等。

关键字defer于注册延迟调用。这些调用直到 ret 前才被执行,通常用于释放资源或错误处理。

一、当defer被声明时,其参数就会被实时解析

?
1
2
3
4
5
6
7
func a() {
  i := 0
  defer fmt.Println(i) //输出0,因为i此时就是0
  i++
  defer fmt.Println(i) //输出1,因为i此时就是1
  return
}

二、当一个函数内多次调用 defer 时,Go 会把 defer 调用放入到一个栈中,随后按照先进后出的顺序执行。

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

输出顺序为4321

使用defer逆序输出字符串

?
1
2
3
4
5
6
7
name := "Naveen你好"
  fmt.Printf("%s\n", string(name))
  fmt.Printf("逆序:")
  defer fmt.Printf("\n")
  for _, v := range []rune(name) {
    defer fmt.Printf("%c", v)
  }

输出:

Naveen你好

逆序:好你neevaN

三、defer 的实际应用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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()
}

我们会发现上面wg.Done()被调用多次我们可以使用defer来优化代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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)
}

使用defer延时调用,会在程序结束之前调用

下面举个例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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("函数返回值:", deferTest(0))
}

上面的代码打印的结果是:

one: 1
two: 2
three: 3
函数返回值: 0

PS:defer 有一个重要的特性,即便函数抛出了异常,defer也会被执行的。这样就不会因为程序出现了错误,导致资源不会被释放了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.jianshu.com/p/bbfe8095ee65

相关文章

热门资讯

歪歪漫画vip账号共享2020_yy漫画免费账号密码共享
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享 2020-04-07
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意 2019-07-07
玄元剑仙肉身有什么用 玄元剑仙肉身境界等级划分
玄元剑仙肉身有什么用 玄元剑仙肉身境界等级划分 2019-06-21
男生常说24816是什么意思?女生说13579是什么意思?
男生常说24816是什么意思?女生说13579是什么意思? 2019-09-17
超A是什么意思 你好a表达的是什么
超A是什么意思 你好a表达的是什么 2019-06-06
返回顶部