美文网首页
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