panic()
?和?recover()
?是 Go 语言中用于处理错误的两个重要函数。panic()
?函数用于中止程序并引发panic,而?recover()
?函数用于捕获panic并恢复程序的执行。
panic()
?函数用于中止程序并引发panic。panic()
?函数可以接收一个参数,该参数将作为panic的原因。recover()
?函数用于捕获panic并恢复程序的执行。recover()
?函数可以接收一个参数,该参数将存储panic的原因。func main() {
defer func() {
err := recover()
if err != nil {
fmt.Println("panic:", err)
}
}()
panic("hello, panic!")
}
?panic 函数会向上传播到调用它的 goroutine。如果 panic 函数没有被捕获,则会一直向上传播,直到遇到 defer
语句中调用的 recover()
函数,或者程序退出。
panic
?和?recover
?不能跨协程使用。这意味着在一个协程中发生的panic只能在同一个协程中通过?recover
?捕获。如果在一个协程中发生了panic,而在另一个协程中调用了?recover
,那么?recover
?将无法捕获panic。参考如下代码:
func main() {
defer println("in main")
go func() {
defer println("in goroutine")
panic("")
}()
time.Sleep(1 * time.Second)
}
如果在一个defer函数中发生了panic,那么该defer函数后面的语句将不会被执行。这意味着在defer函数中使用?recover
?来捕获panic是无效的。
func main(){
defer fmt.Println("main....")
defer func() {
err := recover()
if err != nil {
fmt.Println("panic:", err)
}
}()
panic("hello, panic!")
}
嵌套崩溃是指在一个 goroutine 中调用 panic()
函数,然后在 defer
语句中再次调用 panic()
函数。在这种情况下,panic()
函数会从内向外传播,直到程序崩溃。嵌套崩溃可能会导致程序不可用,因此应避免使用。
func multiplePanic() {
defer fmt.Println("in defer")
defer func() {
defer func() {
panic("panic 3")
}()
panic("panic 2")
}()
panic("panic 1")
}