• 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("触发异常")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    输出:

    打印后
    打印中
    打印前
    panic: 触发异常
    
    • 1
    • 2
    • 3
    • 4

    原理:

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

    也就是压栈式执行的逻辑,栈会遵循先进后出原则,每个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("触发异常")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    输出:

    打印后
    打印中
    触发异常
    打印前
    
    • 1
    • 2
    • 3
    • 4

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


    总结

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


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

  • 相关阅读:
    【Ubuntu】解压 tar.xz 类型文件
    js 正则限制只能输入一位小数
    Structured Streaming join 操作
    智领云独家技术支持,第十届全国高校新一代信息技术暑假师资研修班隆重开营
    Anaconda Linux下安装Anaconda
    MySQL高级:(一)MySQL逻辑架构
    C#开源的一款友好的.NET SDK管理器
    2022了你还不会『低代码』?数据科学也能玩转Low-Code啦! ⛵
    原码,反码,补码 以及 位运算
    tiup cluster start
  • 原文地址:https://blog.csdn.net/moer0/article/details/126494668