Golang 笔试面试学习第一天之defer

Golang 笔试面试学习第一天之defer

Golang轻松学习


个人博客站点:
简书: 😽 猫轻王 https://www.jianshu.com/u/6cce817646be
掘金: 😽 猫轻王 https://juejin.cn/user/1640918680347453
CSDN: 😽 猫轻王 https://blog.csdn.net/moer0
个人项目主页:https://github.com/moercat


一、defer 是什么?

Go语言的 defer 语句会将其后面跟随的语句进行延迟处理,在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。

二、详细代码

1.defer先进后出原则

代码如下(示例):

package main

 import (
     "fmt"
 )

 func main() {
     deferCall()
 }

func deferCall() {
    defer func() { fmt.Println("打印前") }()
    defer func() { fmt.Println("打印中") }()
    defer func() { fmt.Println("打印后") }()
    panic("触发异常")
}

输出:

打印后
打印中
打印前
panic: 触发异常

原理:

其实golang 中的defer 关键字会在 main 函数所有语句之后,return 之前时候调用
压栈式执行,也就是说先注册的函数后调用。
如上,我们注册的顺序式 前,中,后,最后打印结果自然是反着来的,程序输出:
打印后 打印中 打印前
最终才 panic: 触发异常

也就是压栈式执行的逻辑,栈会遵循先进后出原则,每个defer语句都相当于执行一次进栈操作,之后在函数所有语句之后,return 之前时候依次出栈,那么晚进栈的自然早出栈。

2.defer recover 错误捕获

代码如下(示例):

package main

import (
	"fmt"
)

func main() {
	deferError()
}

func deferError() {
	defer func() { fmt.Println("打印前") }()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()
	defer func() { fmt.Println("打印中") }()
	defer func() { fmt.Println("打印后") }()
	panic("触发异常")
}

输出:

打印后
打印中
触发异常
打印前

由于recover 在defer 内提前声明,且defer语句在panic之前,那么defer在所有语句执行结束后便会执行,此时recover 接收到当前程序内的panic抛出的error。程序则不会因为错误中断,而会执行defer内的程序,也就是该程序的 fmt.Println(err)语句,由于defer依旧遵循着先进后出原则,那么即使panic在defer执行前便已运行,却被捕获在defer中间打印


总结

通过以上两个例子可以轻松了解在Golang中defer的使用方式,defer在我们工作中的重要性不言而喻。由于错误捕获与在程序运行后执行的逻辑,非常适合我们的编写中间与进行自定义的错误处理,或者将程序依次上抛进行捕获。


希望这个博客能对你有所益处。我是轻王,我为自己代言。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫轻王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值