golang panic及處理機(jī)制
一 panic機(jī)制
panic會將這個(gè)異常不斷向上拋出,直到有地方處理它,如果有處理,則不會再向上拋出。倘若沒有處理,那么最終會導(dǎo)致main掛掉.
golang雖然沒有try catch機(jī)制,卻有一種類似的recover機(jī)制,后續(xù)demo我們可以觀測到它的用法和作用
二 實(shí)例
2.1 main用recover
func main() {
defer func() {
if err := recover(); err != nil {
log.Println("err:", err)
}
}()
go test1()
time.Sleep(time.Second * 3)
panic(errors.New("stop test1"))
log.Println("123")
select {}
}
func test1() {
for {
tm := time.NewTicker(time.Second)
select {
case <-tm.C:
log.Println("test1")
}
}
}

2.2 func用recover
func main() {
defer func() {
if err := recover(); err != nil {
log.Println("err:", err)
}
}()
go test1()
time.Sleep(time.Second * 3)
makeerr()
log.Println("123")
select {}
}
func test1() {
for {
tm := time.NewTicker(time.Second)
select {
case <-tm.C:
log.Println("test1")
}
}
}
func makeerr() {
defer func() {
if err := recover(); err != nil {
log.Println("makeerr:", err)
}
}()
panic(errors.New("stop"))
}

此時(shí)我們在func中用recover,那么掛掉的只是func,他不會拋到main中,所以main能繼續(xù)運(yùn)行,繼而main開辟的go test1也能繼續(xù)運(yùn)行
2.3 func用recover且開創(chuàng)goroutine
func main() {
defer func() {
if err := recover(); err != nil {
log.Println("err:", err)
}
}()
time.Sleep(time.Second * 3)
makeerr()
log.Println("123")
select {}
}
func test1() {
for {
tm := time.NewTicker(time.Second)
select {
case <-tm.C:
log.Println("test1")
}
}
}
func makeerr() {
defer func() {
if err := recover(); err != nil {
log.Println("makeerr err:", err)
}
}()
go test1()
panic(errors.New("stop test"))
}

我們發(fā)現(xiàn),func雖然掛掉了,但是他開創(chuàng)的go沒掛掉,因?yàn)榧词故沁@個(gè)函數(shù)退出了,新開的協(xié)程是相當(dāng)于基于main下的一個(gè)子程,只要main不退出,他依然會“存活”
2.4 goroutine中panic
func main() {
defer func() {
if err := recover(); err != nil {
log.Println("err:", err)
}
}()
go test1()
time.Sleep(time.Second * 3)
log.Println("123")
select {}
}
func test1() {
log.Println("test1 start")
panic(errors.New("stop test1"))
log.Println("test1 end")
}

協(xié)程中如果沒recover,那么error就會拋向main,main就會掛掉,從而沒有執(zhí)行到后面的log打印。
---> 這種情況,main中做defer recover是沒用的
2.5 func1內(nèi)嵌func2中panic且func2做處理
func main() {
test1()
time.Sleep(time.Second * 3)
log.Println("123")
}
func test1() {
log.Println("test1 start")
test2()
log.Println("test1 end")
}
func test2() {
defer func() {
if err := recover(); err != nil {
log.Println("test2 err:", err)
}
}()
log.Println("test2 start")
panic(errors.New("stop test2"))
log.Println("test2 end")
}

2.6 func1內(nèi)嵌func中panic且func1做處理
func main() {
test1()
time.Sleep(time.Second * 3)
log.Println("123")
}
func test1() {
defer func() {
if err := recover(); err != nil {
log.Println("test? err:", err)
}
}()
log.Println("test1 start")
test2()
log.Println("test1 end")
}
func test2() {
log.Println("test2 start")
panic(errors.New("stop test2"))
log.Println("test2 end")
}

func2異常,執(zhí)行終止,向調(diào)用者func1拋出進(jìn)而本身退出,func1得到異常,執(zhí)行終止,本身退出時(shí)recover進(jìn)行處理,從而保活了main
到此這篇關(guān)于golang panic及處理機(jī)制的文章就介紹到這了,更多相關(guān)golang panic內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
掌握Golang中的select語句實(shí)現(xiàn)并發(fā)編程
Golang中的select語句用于在多個(gè)通道間選擇可讀或可寫的操作,并阻塞等待其中一個(gè)通道進(jìn)行操作??梢杂糜趯?shí)現(xiàn)超時(shí)控制、取消和中斷操作等。同時(shí),select語句支持default分支,用于在沒有任何通道可操作時(shí)執(zhí)行默認(rèn)操作2023-04-04
使用Go語言實(shí)現(xiàn)一個(gè)簡單的詞頻分析系統(tǒng)
在數(shù)據(jù)分析和文本挖掘中,詞頻統(tǒng)計(jì)(Word Frequency Analysis) 是最基礎(chǔ)也是最常用的技術(shù)之一,本文將帶你用 Go 語言實(shí)現(xiàn)一個(gè)簡易的 詞頻分析系統(tǒng),感興趣的小伙伴可以了解下2025-09-09
Golang測試框架goconvey進(jìn)行單元測試流程介紹
goconvey是一款針對Golang的測試框架,可以管理和運(yùn)行測試用例,同時(shí)提供了豐富的斷言函數(shù),并支持很多Web界面特性,這篇文章主要介紹了使用goconvey進(jìn)行單元測試流程,感興趣的同學(xué)可以參考下文2023-05-05
Qt6.5 grpc組件使用 + golang grpc server
這篇文章主要介紹了Qt6.5 grpc組件使用+golang grpc server示例,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05
使用gopacket解析協(xié)議層中的相關(guān)數(shù)據(jù)方式
文章介紹使用Wireshark抓取ping數(shù)據(jù)包并保存為pcap格式,通過Go語言gopacket解析,提取IP版本號、指定標(biāo)識的數(shù)據(jù)包長度及應(yīng)用層ICMP字符串內(nèi)容,展示TCP/IP協(xié)議族解析的簡便方法2025-07-07

