在go例程中处理恐慌

Moh*_*ain -1 recovery go panic

我了解使用了处理紧急恢复的方法。但是当go例程出现恐慌时,以下块无法恢复

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")
    defer func() {
     r := recover()
     if _, ok := r.(error); ok {
        fmt.Println("Recovered")
     }
    }()

    go handle(done)
    for {
        select{
        case <- done:
        return
        }
    } 
}

func handle(done chan int64) {
    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}
Run Code Online (Sandbox Code Playgroud)

但是以下块能够按预期执行

func main() {
    done := make(chan int64)
    defer fmt.Println("Graceful End of program")
    defer func() {
     r := recover()
     if _, ok := r.(error); ok {
        fmt.Println("Recovered")
     }
    }()

    handle(done)
    for {
        select{
        case <- done:
        return
        }
    } 
}

func handle(done chan int64) {
    var a *int64
    a = nil

    fmt.Println(*a)
    done <- *a
}
Run Code Online (Sandbox Code Playgroud)

如何从go例程中出现的恐慌中恢复过来。这是操场的链接:https : //play.golang.org/p/lkvKUxMHjhi

And*_*rew 8

仅当从与调用panic相同的goroutine中调用时,Recover才起作用。

该过程将继续执行堆栈,直到返回当前goroutine中的所有函数为止,此时程序崩溃

您必须在goroutine中进行延迟恢复。

https://blog.golang.org/defer-panic-and-recover

该文档/规范还包括相同的内容:

在执行函数F时,显式调用panic或运行时panic会终止F的执行。然后,照常执行F推迟的任何函数。接下来,运行由F的调用者运行的所有延迟函数,依此类推,直到执行goroutine中顶级函数所延迟的一切 。这时,程序终止,并报告错误情况,包括紧急情况的参数值。此终止序列称为恐慌

https://golang.org/ref/spec#Handling_panics