Go不支持异常抛出和捕获,而是推荐使用返回值显式返回错误。 不过,Go支持一套和异常抛出/捕获类似的机制。此机制称为恐慌/恢复(panic/recover)机制。
我们可以调用内置函数panic来产生一个恐慌以使当前协程进入恐慌状况。
进入恐慌状况是另一种使当前函数调用开始返回的途径。 一旦一个函数调用产生一个恐慌,此函数调用将立即进入它的退出阶段。
通过在一个延迟函数调用之中调用内置函数recover,当前协程中的一个恐慌可以被消除,从而使得当前协程重新进入正常状况。
如果一个协程在恐慌状况下退出,它将使整个程序崩溃

panic后可以重复运行

package main

import (
    "fmt"
    "time"
)

func doSomething(name string) {
    if time.Now().Second()%5 == 0 { // 模拟每5秒触发一次错误
        panic("unexpected situation error")
    }
    fmt.Println(name, " doSomething running smoothly")
}
func shouldNotExit(name string) {
    for {
        doSomething(name)
        time.Sleep(time.Second)
    }
}

func NeverExit(name string, f func()) {
    defer func() {
        if v := recover(); v != nil {
            fmt.Printf("协程%s崩溃了,重新启动一个\n", name)
        }
        go NeverExit(name, f)
    }()
    f()
}

func main() {
    go NeverExit("协程#A", func() { shouldNotExit("协程A") })
    go NeverExit("协程#B", func() { shouldNotExit("协程B") })
    select {}
}