一只萌萌的囊地鼠(Gopher)的求生之路
当小地鼠遇到危险:什么是panic?
想象一下,你正在愉快地 coding,突然程序像一只受惊吓的囊地鼠一样 panic(恐慌)了!这就是Go语言中的宕机机制。
Go语言被设计成一门应用于搭载Web服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。对于高性能分布式系统领域而言,Go语言无疑比大多数其它语言有着更高的开发效率。
但即使是最优秀的程序,也难免会遇到不可预料的错误。这时候,panic就登场了!
panic是Go语言中一种处理严重错误的机制,它类似于其他语言中的异常抛出,但又有其独特之处。当函数执行到panic时,会立即停止当前函数的执行,开始回溯调用栈,并依次执行每个函数中的defer语句,最后打印错误信息和堆栈跟踪,并终止程序。
手动触发panic非常简单:
package main
func main() {
// 一万行代码的辛劳...
panic("一万行也没用,我出毛病了")
// 下面的代码不会执行了
fmt.Println("我不好使了")
}
运行这个程序,你会看到类似这样的输出:
panic: 一万行也没用,我出毛病了
goroutine 1 [running]:
main.main()
/path/to/file.go:7 +0x40
从输出中可以看出,panic不仅告诉了我们错误信息,还提供了完整的堆栈跟踪,这对于调试是非常有帮助的。
那么,什么情况下会触发panic呢?
- 运行时错误:比如数组访问越界、空指针引用等
- 手动触发:当程序遇到无法继续执行的严重错误时,开发者可以手动调用panic函数
- 其他意外情况:如类型断言失败、并发map读写等
但有时候,我们并不希望程序一遇到panic就彻底崩溃,这就是为什么Go还提供了recover机制。
安抚小地鼠的神器:recover登场
有panic没recover,程序宕机。有panic也有recover捕获,程序不会宕机。执行完对应的defer后,从宕机点退出当前函数后继续执行。
recover是Go语言内置的宕机恢复函数,它能够捕获到panic传递的值,并让程序恢复正常执行。
但是,recover有一个重要的特性:它必须在defer函数中调用才能生效。在其他作用域下,它是不工作的。
来看一个简单的例子:
package main
import "fmt"
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
fmt.Println("Before panic")
panic("something bad happened")
fmt.Println("After panic") // 这行不会执行
}
运行结果:
Before panic
Recovered from pan
Go错误处理:宕机与恢复详解

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



