最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang中panic的異常處理

 更新時間:2022年08月17日 10:08:05   作者:CarlosKeFeng  
本文主要介紹了Golang中panic的異常處理,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

Golang中當(dāng)程序發(fā)生致命異常時(比如數(shù)組下標(biāo)越界,注意這里的異常并不是error),Golang程序會panic(運行時恐慌)。當(dāng)程序發(fā)生panic時,程序會執(zhí)行當(dāng)前棧中的defer 函數(shù)列表。然后打印引發(fā)panic的具體信息,最后進程退出,本篇文章我們一起探討Golang中的panic以及如何利用defer 和 recover 來恢復(fù)這種致命的異常

分析造成panic堆棧信息

func main() {
?? ?f1()
?? ?fmt.Println("main func end")
}

func f1() {
?? ?fmt.Println("func f1 start")
?? ?arr := []int{}
?? ?fmt.Println(arr[10])
?? ?fmt.Println("func f1 end")
}

上述代碼中,我在main函數(shù)(主協(xié)程)中調(diào)用了f1函數(shù),在調(diào)用完該函數(shù)后,我打印了「main func end」,程序如果正常執(zhí)行的話會輸出

func f1 start
func f1 end
main func end

很明顯我們可以看出 f1 函數(shù)中,切片arr是沒有索引為10的元素的,這個時候程序運行時會造成panic,下面是程序panic時,console打印的堆棧信息

func f1 start
panic: runtime error: index out of range [10] with length 0
goroutine 1 [running]:
main.f1()
/Users/carlos/go/src/test/demo01.go:15 +0x78
main.main()
/Users/carlos/go/src/test/demo01.go:8 +0x20
Process finished with the exit code 2

我們從堆棧中可以發(fā)現(xiàn):

程序會在造成panic所處的位置終止

我們可以看到錯誤信息中只輸出了 func f1 start

產(chǎn)生panic的原因

panic: runtime error: index out of range [10] with length 0

是哪里造成的panic

goroutine 1 [running] // 運行該程序的協(xié)程
main.f1()
/Users/carlos/go/src/test/demo01.go:15 +0x78 // f1 函數(shù),當(dāng)前demo01文件的低15行
main.main()
/Users/carlos/go/src/test/demo01.go:8 +0x20 // main 函數(shù),當(dāng)前文件的弟8行

從上面的panic詳情我們可以看出,錯誤鏈?zhǔn)峭ㄟ^棧的形式展現(xiàn)出來的(mian函數(shù)先調(diào)用,然后在mian中調(diào)用f1),所以大家以后在程序發(fā)生panic時查看堆棧信息時可以先看最上層的錯誤,因為這里是造成panic的根本原因

如何恢復(fù)panic造成的程序崩潰

Golang中提供了recover函數(shù)用來恢復(fù)因panic造成的程序崩潰。recover函數(shù)有一個返回值來告訴我們panic產(chǎn)生的具體原因。下面我們通過代碼來進行演示

func main() {
?? ?f1()
?? ?r := recover()
?? ?fmt.Printf("%s \n", r)
?? ?fmt.Println("main func end")
}

func f1() {
?? ?fmt.Println("func f1 start")
?? ?arr := []int{}
?? ?fmt.Println(arr[10])
?? ?fmt.Println("func f1 end")
}

上述代碼中我只是在調(diào)用f1函數(shù)的下一行調(diào)用了recover函數(shù),這樣一來我們的理想狀態(tài)了能夠恢復(fù)程序,讓程序執(zhí)行完main函數(shù)中剩下的代碼(打印panic信息,最后打印 main func end),當(dāng)我們運行該程序的時候發(fā)現(xiàn)recover并沒有起到作用,這是因為當(dāng)f1造成panic時,f1下方的recover函數(shù)根本沒有機會執(zhí)行。

下面我將上述代碼進行一個簡單的改造:

func main() {
?? ?defer func() {
?? ??? ?fmt.Println("defer func start")
?? ??? ?if r := recover(); r != nil {
?? ??? ??? ?fmt.Printf("%s \n", r)
?? ??? ?}
?? ??? ?fmt.Println("defer func end")
?? ?}()
?? ?f1()
?? ?fmt.Println("main func end")
}

func f1() {
?? ?fmt.Println("func f1 start")
?? ?arr := []int{}
?? ?fmt.Println(arr[10])
?? ?fmt.Println("func f1 end")
}

輸出

func f1 start
defer func start
runtime error: index out of range [10] with length 0 
defer func end

上述代碼中,我只是在main函數(shù)最開頭添加了一個defer 函數(shù),并在該函數(shù)中調(diào)用了recover函數(shù)。注意,我們在文章的最開頭已經(jīng)說明了,當(dāng)程序發(fā)生panic時,程序會依次執(zhí)行棧中的defer函數(shù)(關(guān)于defer函數(shù)請閱讀官網(wǎng)描述)。所以當(dāng)前程序發(fā)生panic時在進程退出之前會走到defer函數(shù)中執(zhí)行recover函數(shù),recover函數(shù)會恢復(fù)當(dāng)前進程并打印錯誤信息。

這里我需要特別提醒你一點,最好將defer語句寫在函數(shù)的最前面。如果上述例子我將f1的調(diào)用寫在defer函數(shù)之前,你會發(fā)現(xiàn)recover函數(shù)還是沒有執(zhí)行

func main() {
?? ?f1()
?? ?defer func() {
?? ??? ?fmt.Println("defer func start")
?? ??? ?if r := recover(); r != nil {
?? ??? ??? ?fmt.Printf("%s \n", r)
?? ??? ?}
?? ??? ?fmt.Println("defer func end")
?? ?}()
?? ?fmt.Println("main func end")
}

這是因為f1造成panic時,defer函數(shù)根本就沒有壓入函數(shù)調(diào)用棧中。

何時使用panic

當(dāng)你的項目中特別依賴一些組件時,比如一些web項目中經(jīng)常會在進程啟動之前初始化一些mysql,mq句柄。這些實例對業(yè)務(wù)來說是非常重要的,所以當(dāng)這些實例初始化失敗時我們可以直接讓當(dāng)前程序panic(手動panic),然后及時發(fā)現(xiàn)問題并解決。這樣總比你帶著問題上線后,然后一批流入打入進來,客戶端瘋狂報錯要好

Golang中手動調(diào)用panic:

func main() {
?? ?initMysql()
}

func initMysql() {
?? ?panic("init mysql failed") // panic可以接收一個interface類型的參數(shù)
}

到此這篇關(guān)于Golang中panic的異常處理的文章就介紹到這了,更多相關(guān)Golang panic內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言實現(xiàn)Kafka消息隊列的示例代碼

    Go語言實現(xiàn)Kafka消息隊列的示例代碼

    本文主要介紹了Go語言實現(xiàn)Kafka消息隊列的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • 3個Go語言中實用重構(gòu)技術(shù)分享

    3個Go語言中實用重構(gòu)技術(shù)分享

    代碼重構(gòu)是在不改變外部功能的情況下對現(xiàn)有代碼進行改進,是編程的核心部分之一,本文為大家介紹了Go語言中3個實用重構(gòu)技術(shù),需要的可以參考一下
    2023-06-06
  • golang交叉編譯詳細

    golang交叉編譯詳細

    Golang 支持交叉編譯,在一個平臺上生成另一個平臺的可執(zhí)行程序,只需要按照我下面的這個環(huán)境變量表設(shè)置對應(yīng)的環(huán)境變量就可以了,下面文章將對該內(nèi)容做詳細介紹,感興趣的小伙伴可以參考一下
    2021-10-10
  • 使用Go語言實現(xiàn)遠程傳輸文件

    使用Go語言實現(xiàn)遠程傳輸文件

    本文主要介紹如何利用Go語言實現(xiàn)遠程傳輸文件的功能,有需要的小伙伴們可以參考學(xué)習(xí)。下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)。
    2016-08-08
  • Golang中自定義json序列化時間格式的示例代碼

    Golang中自定義json序列化時間格式的示例代碼

    Go語言作為一個由Google開發(fā),號稱互聯(lián)網(wǎng)的C語言的語言,自然也對JSON格式支持很好,下面這篇文章主要介紹了關(guān)于Golang中自定義json序列化時間格式的相關(guān)內(nèi)容,下面話不多說了,來一起看看詳細的介紹吧
    2024-08-08
  • omitempty在go中的使用方式

    omitempty在go中的使用方式

    在Go語言編程中,`omitempty`標(biāo)記用于JSON編解碼過程中控制字段是否被包含,當(dāng)結(jié)構(gòu)體字段標(biāo)記為`omitempty`且字段值為空時,該字段不會出現(xiàn)在生成的JSON中,有助于優(yōu)化JSON結(jié)構(gòu)和減小數(shù)據(jù)體積,通過具體示例解釋了`omitempty`的工作機制和實際效果
    2024-09-09
  • 一文了解Go 并發(fā)與并行

    一文了解Go 并發(fā)與并行

    并發(fā)性和并行性是是兩個既有聯(lián)系又有所區(qū)別的概念,本文主要介紹了Go并發(fā)與并行,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Golang分布式鎖詳細介紹

    Golang分布式鎖詳細介紹

    分布式鎖是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式。如果不同的系統(tǒng)或是同一個系統(tǒng)的不同主機之間共享了一個或一組資源,那么訪問這些資源時,需要通過一些互斥手段來防止彼此之間的干擾以保證一致性,在這種情況下,就需要使用分布式鎖了
    2022-10-10
  • 深入解析Sync.Pool如何提升Go程序性能

    深入解析Sync.Pool如何提升Go程序性能

    在并發(fā)編程中,資源的分配和回收是一個很重要的問題。Go?語言的?Sync.Pool?是一個可以幫助我們優(yōu)化這個問題的工具。本篇文章將會介紹?Sync.Pool?的用法、原理以及如何在項目中正確使用它,希望對大家有所幫助
    2023-05-05
  • Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實例詳解

    Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實例詳解

    這篇文章主要介紹了Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-02-02

最新評論

托克托县| 长岭县| 呼玛县| 桦甸市| 广宁县| 石柱| 寿宁县| 龙陵县| 密云县| 天津市| 东海县| 安庆市| 蛟河市| 黄骅市| 白河县| 曲麻莱县| 南皮县| 谢通门县| 邵东县| 临安市| 桐城市| 新疆| 澳门| 沧源| 汤原县| 丰台区| 当阳市| 海城市| 班戈县| 砀山县| 汉阴县| 陈巴尔虎旗| 凯里市| 井陉县| 厦门市| 思南县| 高清| 永城市| 兴文县| 互助| 云和县|