102人参与 • 2025-04-24 • Golang
当然能触发程序宕机退出的,也可以是我们自己,比如经过检查判断,当前环境无法达到我们程序进行的预期条件时(比如一个服务指定监听端口被其他程序占用),可以手动触发 panic,让程序退出停止运行。
手动触发宕机,是非常简单的一件事,只需要调用 panic 这个内置函数即可,就像这样子
package main
func main() {
panic("crash")
}
运行结果:
panic: crash
goroutine 1 [running]:
main.main()
d:/goworks/src/尚硅谷/异常处理/demo01.go:4 +0x25
exit status 2
发生了异常,有时候就得捕获,就像 python 中的except 一样,那 golang 中是如何做到的呢?
这就不得不引出另外一个内建函数 – recover,它可以让程序在发生宕机后起生回生。
但是 recover 的使用,有一个条件,就是它必须在 defer 函数中才能生效,其他作用域下,它是不工作的。
这是一个简单的例子
package main
import "fmt"
func set_data(x int) {
defer func() {
// recover() 可以将捕获到的panic信息打印
if err := recover(); err != nil {
fmt.println(err)
}
}()
// 故意制造数组越界,触发 panic
var arr [10]int
arr[x] = 88
}
func main() {
set_data(20)
// 如果能执行到这句,说明panic被捕获了
// 后续的程序能继续运行
fmt.println("everything is ok")
}
运行结果:
捕获到panic后正常运行。
runtime error: index out of range [20] with length 10 everything is ok
从上面的例子,可以看到,即使 panic 会导致整个程序退出,但在退出前,若有 defer 延迟函数,还是得执行完 defer 。
但是这个 defer 在多个协程之间是没有效果,在子协程里触发 panic,只能触发自己协程内的 defer,而不能调用 main 协程里的 defer 函数的。
来做个实验就知道了
package main
import (
"fmt"
"time"
)
func main() {
// 这个 defer 并不会执行
defer fmt.println("in main")
go func() {
defer println("in goroutine")
// 这个panic就会终止程序
// 在这终止了外面的defer也不会执行
panic("")
}()
time.sleep(2 * time.second)
}
输出如下,并没有执行defer fmt.println(“in main”)
in goroutine
panic:
goroutine 19 [running]:
main.main.func1()
d:/goworks/src/尚硅谷/异常处理/demo03.go:14 +0x3e
created by main.main in goroutine 1
d:/goworks/src/尚硅谷/异常处理/demo03.go:12 +0x59
exit status 2
golang 异常的抛出与捕获,依赖两个内置函数:
revocer 调用后,抛出的 panic 将会在此处终结,不会再外抛,但是 recover,并不能任意使用,它有强制要求,必须得在 defer 下才能发挥用途。
到此这篇关于go 异常处理panic和recover的简单实践的文章就介绍到这了,更多相关go 异常处理panic和recover内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论