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 {}
}