Golang Defer Panic && Recover

Go 语言的针对错误处理机制,提供了三个关键字 defer,panic 和 recover。同传统的 try-catch 语句不同,defer 的出现,不需要层层进行 try-catch 的嵌套。

defer 语句的作用是保证 defer 内的语句在最后执行,哪怕程序运行错误,defer 语句还是会执行后然后结束程序。类似于程序运行完之后的清扫工作。

defer 语句可以理解为注册了几个自定义的 clean-up 函数,如果一个 defer 语句的函数被执行,那么这个 defer 语句包裹的函数就会被注册,然后在最后执行。

defer 语句的使用有几个需要注意的地方

  • defer 语句包裹的函数,其参数在 defer 语句被执行的时候就要被求值。并且在使用 defer 语句包裹的时候,就要进行调用。
func a() {
    i := 0
    defer fmt.Println(i)
    i ++
    return 
}

此时,在defer 运行的时候,i 被求值,为 0 ,传入 Print 函数中。

  • 如果有多个 defer 语句包括的函数,那么这些函数遵从 FILO 的原则,依次执行。
  • defer 函数可以读取函数返回的值,进行操作,甚至修改返回值
func c() (i int) {
    defer func() { i++ }()
    return 1
}

这个时候,defer 直接修改了原本的返回值,所以,返回值为 2 。

Panic-recover 语句
Panic-recover 语句是 Go 语言提出用来进行错误异常处理的关键词。
Panic 语句可以让程序陷入一种恐慌的状态,程序会停止原先的 workflow,然后按顺序依次执行 defer 过的语句,然后返回调用的函数,对于调用者而言,此时也陷入了恐慌的状态。然后持续之前的动作,直到此时的 goroutine 中全部返回,然后程序 crash 掉。整个程序的 panic 状态可能有多个原因造成,数组的越界或者对 nil 的操作都会导致程序的 panic 状态,当然,我们显示的调用 panic() 函数也会导致程序进入 panic 状态。

Recover 语句则是用来对 panic 状态的程序进行恢复的语句。recover 函数只有其在 defer 中进行调用的时候才会有效,如果在 defer 外进行调用,则无效。如果程序没有进入恐慌状态,那么 recover 函数则返回 nil,反之,recover 函数返回调用 panic 函数时的参数。然后让程序恢复正常。

下面给出一个完整的例子,理解了例子,也就理解了 defer,panic,recover 的用法。

package main

import "fmt"

func main() {
    f()
    fmt.Println("Returned normally from f.")
}

func f() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered in f", r)
        }
    }()
    fmt.Println("Calling g.")
    g(0)
    fmt.Println("Returned normally from g.")
}

func g(i int) {
    if i > 3 {
        fmt.Println("Panicking!")
        panic(fmt.Sprintf("%v", i))
    }
    defer fmt.Println("Defer in g", i)
    fmt.Println("Printing in g", i)
    g(i + 1)
}

Go routine 和 panic
Go 语言是内置了多协程的语言,那么在多个协程的时候,出现了 Panic,该如何处理呢。
Go 语言中,defer 调用的时候,会将调用的 goroutine 的协程和 defer 调用的函数进行关联。defer 调用的函数对应的各自协程中的状态。所以,如果遇到了跨协程的时候,跨协程的 defer recover 会失效,即两个协程之间互不干扰。一个 goroutine 在 panic 的时候,不会调用其他 goroutine 的延迟函数。
但是一个 goroutine 的运行的panic,如果没有很好的处理,也会影响其他 goroutine 的运行。

所以,对于多协程的时候,应该各自的 goroutine 处理各自的 panic 状况。

猜你喜欢

转载自www.cnblogs.com/wAther/p/12285715.html