一文帶你掌握Golang中panic與recover的使用方法
panic
panic作用是終止當(dāng)前正在運(yùn)行的程序(包括所有協(xié)程)并輸出導(dǎo)致異常的堆棧信息。在遇到無(wú)法處理的異常情況時(shí),例如比如數(shù)組越界、操作未初始化的map、空指針等都會(huì)觸發(fā)panic。主動(dòng)觸發(fā)panic示例:
package main
func main() {
// 未處理的自定義異常
customException := "an error occurred"
panic(customException)
}
會(huì)輸出如下信息:
panic: an error occurred
goroutine 1 [running]:
main.main()
/Users/ning/projects/go/workspace/hello/panic/main.go:7 +0x34
Process finished with the exit code 2
數(shù)據(jù)越界導(dǎo)致panic示例:
package main
import "fmt"
func main() {
a := [2]int{4, 5}
fmt.Println(a[3])
}
會(huì)輸出如下信息:
# command-line-arguments
./main.go:11:16: invalid argument: array index 3 out of bounds [0:2]
Compilation finished with exit code 2
recover
recover可以讓觸發(fā)了panic的程序繼續(xù)運(yùn)行,recover僅在延遲函數(shù)defer中有效,在正常的執(zhí)行過(guò)程中,調(diào)用recover會(huì)返回nil并且不產(chǎn)生其他任何效果。如果當(dāng)前的goroutine觸發(fā)了panic,調(diào)用recover可以捕獲到panic的輸入值,并且恢復(fù)正常運(yùn)行。這個(gè)特性對(duì)于像web服務(wù)就非常有用了, 當(dāng)web服務(wù)處理某個(gè)請(qǐng)求時(shí),某個(gè)方法觸發(fā)了panic,這時(shí)候顯然是不應(yīng)該直接讓web服務(wù)掛掉的。這種場(chǎng)景下,就可以使用recover來(lái)捕獲panic并且讓服務(wù)正常運(yùn)行下去。
在其他語(yǔ)言里,通常是底層拋出異常,上層邏輯通過(guò)try/catch捕獲異常。defer/panic/recover配合使用可以實(shí)現(xiàn)類似try/catch的功能。
將Recover()寫在defer中,在可能發(fā)生panic的代碼之前執(zhí)行defer,當(dāng)程序觸發(fā)panic后,系統(tǒng)將跳過(guò)后面的代碼,按照逆序執(zhí)行已經(jīng)注冊(cè)的defer函數(shù),如果defer函數(shù)中調(diào)用了recover(),recover()會(huì)返回捕獲到的panic的錯(cuò)誤信息。
使用recover需要注意幾點(diǎn):
- recover需要在defer的方法里面直接調(diào)用,不能對(duì)recover()包一層方法后再在defer的方法里面調(diào)用
- recover只能捕獲同一個(gè)協(xié)程中的panic,無(wú)法捕獲其它協(xié)程的panic
defer/panic/recover示例
成功捕獲實(shí)例一
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("recover:%v\n", err)
}
}()
panic("an error occurred")
}成功捕獲實(shí)例二
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("recover:%v\n", err)
}
}()
test()
}
func test() {
panic("an error occurred")
}
成功捕獲實(shí)例三
func main() {
test()
}
func test() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("recover:%v\n", err)
}
}()
panic("an error occurred")
}
不能捕獲實(shí)例一
func main() {
if err := recover(); err != nil {
fmt.Printf("recover:%v\n", err)
}
panic("an error occurred")
}
不能捕獲實(shí)例二
func main() {
go func() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("recover:%v\n", err)
}
}()
}()
panic("an error occurred")
}
不能捕獲實(shí)例三
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("recover:%v\n", err)
}
}()
go test()
for {
select {}
}
}
func test() {
panic("an error occurred")
}
不能捕獲實(shí)例四
func main() {
defer func() {
recoverFromPanic()
}()
test()
}
func recoverFromPanic() {
if err := recover(); err != nil {
fmt.Printf("recover:%v\n", err)
}
}
func test() {
panic("an error occurred")
}
不能捕獲實(shí)例五
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("recover:%v\n", err)
}
}()
test()
for {
select {}
}
}
func test() {
go func() {
panic("an error occurred")
}()
}以上就是一文帶你掌握Golang中panic與recover的使用方法的詳細(xì)內(nèi)容,更多關(guān)于Golang panic recover的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang 獲取系統(tǒng)信息的實(shí)現(xiàn)
本文主要介紹了Golang 獲取系統(tǒng)信息的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
Golang語(yǔ)言中的Prometheus的日志模塊使用案例代碼編寫
這篇文章主要介紹了Golang語(yǔ)言中的Prometheus的日志模塊使用案例,本文給大家分享源代碼編寫方法,感興趣的朋友跟隨小編一起看看吧2024-08-08
詳解golang避免循環(huán)import問(wèn)題(“import cycle not allowed”)
這篇文章主要給大家介紹了關(guān)于golang中不允許循環(huán)import問(wèn)題("import cycle not allowed")的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
利用Go語(yǔ)言搭建WebSocket服務(wù)端方法示例
這篇文章主要給大家介紹了利用Go語(yǔ)言搭建WebSocket服務(wù)端方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2017-04-04
使用Golang快速構(gòu)建出命令行應(yīng)用程序
在日常開發(fā)中,大家對(duì)命令行工具(CLI)想必特別熟悉了,如果說(shuō)你不知道命令工具,那你可能是個(gè)假開發(fā)。每天都會(huì)使用大量的命令行工具,例如最常用的Git、Go、Docker等,這篇文章主要介紹了使用Golang快速構(gòu)建出命令行應(yīng)用程序,需要的朋友可以參考下2023-02-02
Golang實(shí)現(xiàn)異步上傳文件支持進(jìn)度條查詢的方法
這篇文章主要介紹了Golang實(shí)現(xiàn)異步上傳文件支持進(jìn)度條查詢的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
Go?語(yǔ)言進(jìn)階freecache源碼學(xué)習(xí)教程
這篇文章主要為大家介紹了Go?語(yǔ)言進(jìn)階freecache源碼學(xué)習(xí)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04

