• defer、panic、recover


    defer(延迟执行语句)

    多个延迟执行语句的处理顺序

    package main
    import (
        "fmt"
    )
    func main() {
        fmt.Println("defer begin")
        // 将defer放入延迟调用栈
        defer fmt.Println(1)
        defer fmt.Println(2)
        // 最后一个放入, 位于栈顶, 最先调用
        defer fmt.Println(3)
        fmt.Println("defer end")
    }

    结果分析如下:

    • 代码的延迟顺序与最终的执行顺序是反向的。
    • 延迟调用是在 defer 所在函数结束时进行,函数结束可以是正常返回时,也可以是发生宕机时。

    使用延迟执行语句在函数退出时释放资源

    处理业务或逻辑中涉及成对的操作是一件比较烦琐的事情,比如打开和关闭文件、接收请求和回复请求、加锁和解锁等。在这些操作中,最容易忽略的就是在每个函数退出处正确地释放和关闭资源。
    defer 语句正好是在函数退出时执行的语句,所以使用 defer 能非常方便地处理资源释放问题。

    panic——程序终止运行

    package main
    func main() {
        panic("crash")
    }

    在宕机时触发延迟执行语句

    当 panic() 触发的宕机发生时,panic() 后面的代码将不会被运行,但是在 panic() 函数前面已经运行过的 defer 语句依然会在宕机发生时发生作用,参考下面代码

    package main
    import "fmt"
    func main() {
        defer fmt.Println("宕机后要做的事情1")
        defer fmt.Println("宕机后要做的事情2")
        panic("宕机")
    }

    输出结果为:

    宕机后要做的事情2
    宕机后要做的事情1
    panic: 宕机
    
    goroutine 1 [running]:
    main.main()
        F:/src/tester/main.go:8 +0x1a4

    recover

    无论是代码运行错误由 Runtime 层抛出的 panic 崩溃,还是主动触发的 panic 崩溃,都可以配合 defer 和 recover 实现错误捕捉和恢复,让代码在发生崩溃后允许继续运行。

    defer func() {
        if r:= recover();r != nil{
            log.Printf("Runtime error caught :%v",r)
        }
    }()
    
    foo()
  • 相关阅读:
    1055. [HAOI2008]玩具取名【区间DP】
    BZOJ2435:[NOI2011]道路修建 (差分)
    1084. [SCOI2005]最大子矩阵【网格DP】
    1060. [ZJOI2007]时态同步【树形DP】
    1050. [HAOI2006]旅行【并查集+枚举】
    2463. [中山市选2009]谁能赢呢?【博弈论】
    luogu P1195 口袋的天空
    luogu P1162 填涂颜色
    luogu P1223 排队接水
    luogu P1331 海战
  • 原文地址:https://www.cnblogs.com/domestique/p/9978321.html
Copyright © 2020-2023  润新知