golang中的defer使用方式及实战技巧

golang是一门简洁、高效、并发友好的编程语言,它提供了许多独特的特性,让程序员可以更容易地编写优雅和健壮的代码。其中一个特性就是defer语句,它可以让我们在函数返回之前执行一些清理或收尾的操作,比如关闭文件、释放资源、解锁互斥量等。defer语句的语法很简单,就是在要延迟执行的函数或方法前加上关键字defer,如下所示:

func main() {
   
    f, err := os.Open("test.txt")
    if err != nil {
   
        log.Fatal(err)
    }
    defer f.Close() // 延迟关闭文件
}

在这个例子中,我们打开了一个文件,并在函数返回之前延迟关闭它,这样可以确保不会因为忘记关闭文件而造成资源泄露。

一、多个defer的执行顺序

defer语句的执行顺序是按照后进先出(LIFO)的原则,也就是说,最后一个defer语句会最先执行,第一个defer语句会最后执行。例如:

func main() {
   
    defer fmt.Println("A")
    defer fmt.Println("B")
    defer fmt.Println("C")
}

这个程序的输出是:

C
B
A

二、参数赋值的时间

参数的赋值对于有的同学来说一只都是一个难题,那defer是什么时候确定参数的值的呢?我们先来比较下面两个语句输出的差异:

func main() {
   
    x := 1
    defer fmt.Println(x)
    x = 2
}

这个程序的输出是:

1
	x := 1
	defer func() {
   
		fmt.Println(x)
	}()
	x = 2

这个程序的输出是:

2

如果熟悉go异步编程的小伙伴应该不会觉得惊讶。原因defer 调用的函数参数的值在 defer 定义时就确定了, 而 defer 函数内部所使用的变量的值需要在这个函数运行时才确定。所以如果我们想在第二个例子中输出1的话,需要做如下的改造:

func main() {
   
    x := 1
    defer func(x int) {
   
        fmt.Println(x) // x = 1
    }(x)
    x = 2
}

三、执行表达式

除了可以延迟执行函数或方法外,defer语句还可以延迟执行任意的表达式,只要它们能被求值为一个函数调用。例如:

func main() {
   
    defer
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值