欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang中panic的實現(xiàn)示例

 更新時間:2025年06月23日 10:51:57   作者:CarlosKeFeng  
這篇文章主要介紹了Golang中panic的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

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

分析造成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é)程)中調用了f1函數(shù),在調用完該函數(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

  • 產生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ù),當前demo01文件的低15行
main.main()
/Users/carlos/go/src/test/demo01.go:8 +0x20 // main 函數(shù),當前文件的弟8行

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

如何恢復panic造成的程序崩潰

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

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")
}

上述代碼中我只是在調用f1函數(shù)的下一行調用了recover函數(shù),這樣一來我們的理想狀態(tài)了能夠恢復程序,讓程序執(zhí)行完main函數(shù)中剩下的代碼(打印panic信息,最后打印 main func end),當我們運行該程序的時候發(fā)現(xiàn)recover并沒有起到作用,這是因為當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ù)中調用了recover函數(shù)。注意,我們在文章的最開頭已經說明了,當程序發(fā)生panic時,程序會依次執(zhí)行棧中的defer函數(shù)(關于defer函數(shù)請閱讀官網描述)。所以當前程序發(fā)生panic時在進程退出之前會走到defer函數(shù)中執(zhí)行recover函數(shù),recover函數(shù)會恢復當前進程并打印錯誤信息。

這里我需要特別提醒你一點,最好將defer語句寫在函數(shù)的最前面。如果上述例子我將f1的調用寫在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ù)調用棧中。

何時使用panic

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

Golang中手動調用panic:

func main() {
	initMysql()
}

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

到此這篇關于Golang中panic的實現(xiàn)示例的文章就介紹到這了,更多相關Golang panic內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • 記一次go語言使用time.Duration類型踩過的坑

    記一次go語言使用time.Duration類型踩過的坑

    本文主要介紹了記一次go語言使用time.Duration類型踩過的坑,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Go計算某段代碼運行所耗時間簡單實例

    Go計算某段代碼運行所耗時間簡單實例

    這篇文章主要給大家介紹了關于Go計算某段代碼運行所耗時間的相關資料,主要介紹了Golang記錄計算函數(shù)執(zhí)行耗時、運行時間的一個簡單方法,文中給出了詳細的代碼示例,需要的朋友可以參考下
    2023-11-11
  • Go泛型的理解和使用小結

    Go泛型的理解和使用小結

    泛型是一種非常強大的編程技術,可以提高代碼的復用性和可讀性,通過泛型容器和類型參數(shù)化,Go語言中的泛型可以實現(xiàn)更加靈活和通用的編程,提高代碼的復用性和可維護性,本文給大家介紹Go泛型的理解和使用,感興趣的朋友一起看看吧
    2023-12-12
  • 詳解如何在Go語言中生成隨機種子

    詳解如何在Go語言中生成隨機種子

    這篇文章主要為大家詳細介紹了如何在Go語言中生成隨機種子,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2024-04-04
  • 使用Go語言實現(xiàn)在項目中隱藏敏感信息

    使用Go語言實現(xiàn)在項目中隱藏敏感信息

    在開發(fā)項目是,用戶信息管理是一個非常常見的場景,特別是當我們需要存儲和處理敏感信息時,本文主要介紹了如何使用Go語言實現(xiàn)隱藏敏感信息,需要的可以參考下
    2024-11-11
  • golang實現(xiàn)unicode轉換為字符串string的方法

    golang實現(xiàn)unicode轉換為字符串string的方法

    這篇文章主要介紹了golang實現(xiàn)unicode轉換為字符串string的方法,實例分析了Go語言編碼轉換的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2016-07-07
  • go語言單例模式(Singleton)實例分析

    go語言單例模式(Singleton)實例分析

    這篇文章主要介紹了go語言單例模式(Singleton),實例分析了單例模式的原理與Go語言的實現(xiàn)技巧,需要的朋友可以參考下
    2015-03-03
  • golang抓取tcp包的實現(xiàn)方式

    golang抓取tcp包的實現(xiàn)方式

    使用`golang`的`packet`和`pcap`庫可以抓取TCP數(shù)據(jù)包,首先,確保安裝了`pcap`庫,然后使用以下代碼打開網絡接口,設置過濾規(guī)則為“tcp”,開始捕獲并解析TCP數(shù)據(jù)包,運行代碼時需要管理員權限
    2024-12-12
  • 深入Golang之context的用法詳解

    深入Golang之context的用法詳解

    本篇文章主要介紹了深入Golang之context的用法詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • GO語言make和new關鍵字的區(qū)別

    GO語言make和new關鍵字的區(qū)別

    本篇文章來介紹一道非常常見的面試題,到底有多常見呢?可能很多面試的開場白就是由此開始的。那就是?new?和?make?這兩個內置函數(shù)的區(qū)別,希望對大家有所幫助
    2023-04-04

最新評論