美文网首页
defer panic recover

defer panic recover

作者: cdz620 | 来源:发表于2020-03-08 22:57 被阅读0次

    背景

    在go语言里设计里,普通语言try catch处理异常的机制,破坏了程序流程控制,降低可读性,与维护成本。
    在go里,认为异常(error)应该为函数的返回值,调用方应该在任何时候都要判断函数的返回值是否有异常,再根据结果执行后续的代码。
    go基于此特性,go增加了defer, recover可对程序更灵活的流程控制

    defer

    三种规则:

    • defer 的函数的参数为当前参数的快照值,后续如果有对该变量变化,在defer 函数执行时,还是未变化之前的值。相当于参数提前保存。
    func a() {
        i := 0
        defer fmt.Println(i)
        i++
        return
    }
    # output
    # 0 // not 1
    
    • defer 函数队列,为后进先出队列
    func b() {
        for i := 0; i < 4; i++ {
            defer fmt.Print(i)
        }
    }
    # output 
    # 3210
    
    • defer 函数里,可以改变命名返回变量的值
    func c() (i int) {
        defer func() { i++ }()
        return 1
    }
    # output
    # 2 // 注意不是1
    

    注意事项

    Q: defer队列里的函数,执行产生异常,队列里后面的函数会继续执行吗?
    A: defer 设计为资源回收处理动作,保证defer函数队列里的函数,都会被执行
    测试例子:https://play.golang.org/p/P7CNK3DNgDf

    package main
    
    import "fmt"
    
    func main() {
        f()
        fmt.Println("returned from func main")
    }
    
    func f() {
        defer func() {
            fmt.Println("defer level 1")
        }()
        defer func() {
            fmt.Println("defer level 2, panicking")
            var i = 100
            _ = 5 / (i-i)
        }()
        defer func() {
            fmt.Println("defer level 3, panicking")
            var i = 100
            _ = 5 / (i-i)
        }()
        fmt.Println("in func f")
        fmt.Println("returned from func f")
    }
    

    相关文章

      网友评论

          本文标题:defer panic recover

          本文链接:https://www.haomeiwen.com/subject/xhjsdhtx.html