defer panic recover

2020-03-08  本文已影响0人  cdz620

背景

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

defer

三种规则:

func a() {
    i := 0
    defer fmt.Println(i)
    i++
    return
}
# output
# 0 // not 1
func b() {
    for i := 0; i < 4; i++ {
        defer fmt.Print(i)
    }
}
# output 
# 3210
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")
}
上一篇 下一篇

猜你喜欢

热点阅读