GO基础笔记(一) defer详解

本文详细介绍了Go语言中的defer特性,包括其在释放资源、执行顺序、与return的关系、处理panic及recover的使用,以及defer参数陷阱的解析,揭示了defer执行背后的逻辑和注意事项。
摘要由CSDN通过智能技术生成

defer是Golang一大语言特色,它扮演的是类似Java中finally的角色。用于执行释放资源的一些操作。

defer语句定义在函数内,后面跟一个函数,被defer的函数会在defer所在的函数结果前被执行。defer能够保证函数不管以何种方式结束(return或panic),被defer的函数一定被执行。

释放资源

defer可以被定义在函数中的任何地方,这意味着当我们打开一个资源,马上可以使用defer声明它的释放,这样我们在编写后面的代码的时候就不用操心这个资源的释放了。函数结束的时候会自动执行释放操作:

func ReadFile() error {
   
    // 打开了一些资源
    file, err := os.Open("file")
    if err != nil {
   
        return err
    }
    // 这条语句会自动在函数结束时执行
    defer file.Close()

    // 继续执行后面的操作,而不用操心file的释放了
    ...
}

这就是defer的一般用法了,当然,defer远没有这么简单,下面我们来扣扣defer的语法细节:

多个defer的执行顺序

如果一个函数里面有多个defer,那么会如何执行呢?观察下面的代码:

package main

import "fmt"

func main() {
   
    deferFunc()
}

func deferFunc() {
   

    defer fmt.Println("exec 1")
    defer fmt.Println("exec 2")
    defer fmt.Println("exec 3")

}

注意,defer的执行顺序遵循后进先出的原则,后面的defer语句将会被先执行,因此执行的顺序应该是从下至上的,下面是输出:

exec 3
exec 2
exec 1

我们只需要知道defer是从下到上执行的即可。

defer和return的顺序

defer的顺序还有更加深层次的话题,那就是defer和return之间的执行顺序。

观察下面的代码:

package main

import "fmt"

func main() {
   

	fmt.Println(deferReturn())
}

func deferReturn() (i int) {
   

	defer func() {
   
		i += 3
	}()

	i = 3

	return
}

执行一下,结果输出"6"。这说明,defer是在函数return之前执行的。而具名返回参数i的作用域是整个函数,因此理所当然地,defer可以访问i并对其做修改。

defer和panic

当函数遇到panic,defer仍然会被执行。Go会先执行所有的defer链表(该函数的所有defer),当所有defer被执行完毕且没有recover时,才会进行panic。

package main

import 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值