Go学习之旅之defer函数 |Go主题月

221 阅读1分钟

前文索引:juejin.cn/post/695390…

一、defer

1. 作用

  • 用defer关键字修饰的语句会被延迟到函数即将返回前执行

  • defer常被用于在函数调用结束后,进行一些收尾工作,如关闭文件描述符、关闭数据库连接以及解锁资源等

  • 当存在多个defer语句时,执行顺序类似于数据结构中栈的形式,先进后出

代码示例:

package main
import "fmt"

func deferDemo(){
	fmt.Println("start")
	defer fmt.Println("defer1")//defer将该条语句延迟到函数即将返回前执行
	defer fmt.Println("defer2")//多个defer执行,类似于数据结构中栈的形式,先进后出
	defer fmt.Println("defer3")
	fmt.Println("end")
}

func main(){
	deferDemo()
 }

2. defer在return中执行顺序

在Go中,return语句不是原子操作,而是被拆成了两步:

package main
import "fmt"

func f1(x int,y int) int{
	return x+y
}

func main(){
	f1()
 }
  1. 返回值等于x+y;
  2. ret指令

而defer语句就是在这两步之间执行:

  1. 返回值等于XXX
  2. defer
  3. ret指令

更进一步解释,请看下面例子:

package main

func f() int {
    i := 5
    defer func() {
        i++
    }()
    return i
}

func f1() (result int) { 
    defer func() { 
        result++ 
    }() 
    return 0
}

func f2() (r int) { 
    t := 5 
    defer func() { 
        t = t + 5 
    }()
    return t
}

func main() {
    println(f())
    println(f1())
    println(f2())
}

输出结果:

5
1
5

解释:

对于f(),返回值等于5(此时i为5),执行defer,i++(i变为6),返回5;

对于f1(),返回值为result,执行defer,result++,result变为1,返回result(1);

对于f2(),返回值为r(此时r等于t,为5),执行defer,t变为10,返回r(5)。