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

Go語(yǔ)言中panic和recover的實(shí)現(xiàn)

 更新時(shí)間:2025年10月19日 11:43:46   作者:可能只會(huì)寫B(tài)UG  
本文主要介紹了Go語(yǔ)言中panic和recover的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

Go 語(yǔ)言的 panic 和 recover 是兩種用于處理異常的機(jī)制。

它們?cè)试S在程序運(yùn)行過(guò)程中進(jìn)行錯(cuò)誤處理,特別是處理那些不可恢復(fù)的錯(cuò)誤和恢復(fù)程序的執(zhí)行。

panic 和 recover 并不像其他語(yǔ)言中的 try-catch 機(jī)制那樣常見,而是提供了控制程序流程的一種方法。

panic 機(jī)制

panic 用于表示程序遇到了一個(gè)不可恢復(fù)的錯(cuò)誤,或者程序處于一個(gè)不應(yīng)繼續(xù)執(zhí)行的狀態(tài)。它會(huì)觸發(fā)運(yùn)行時(shí)的異常,并停止當(dāng)前函數(shù)的執(zhí)行,直到調(diào)用 recover 或程序退出。

1.1 panic 的使用

當(dāng)你遇到一個(gè)嚴(yán)重的錯(cuò)誤或不合法的操作時(shí),可以調(diào)用 panic 來(lái)終止當(dāng)前函數(shù)的執(zhí)行,并開始觸發(fā)一系列的 defer 函數(shù)。

panic 會(huì)導(dǎo)致當(dāng)前函數(shù)的執(zhí)行停止,并且會(huì)遞歸地向上層函數(shù)傳播,直到程序結(jié)束或者有 recover 恢復(fù)它。

使用 panic 終止程序

func divide(a, b int) int {
	if b == 0 {
		panic("division by zero") // 如果除數(shù)為零,拋出 panic
	}
	return a / b
}

func main() {
	fmt.Println("Starting program")

	// 這里會(huì)觸發(fā) panic
	result := divide(10, 0)

	fmt.Println("Result:", result) // 這行代碼不會(huì)執(zhí)行
}
當(dāng) b == 0 時(shí),panic 被觸發(fā),程序會(huì)停止當(dāng)前函數(shù)的執(zhí)行,并開始遞歸傳播。

panic 的錯(cuò)誤信息是 "division by zero",這將顯示在控制臺(tái)。

調(diào)用 panic 后,程序停止執(zhí)行,任何后續(xù)代碼都不會(huì)被執(zhí)行,除非在調(diào)用鏈中有 recover。

recover 機(jī)制

recover 是 Go 語(yǔ)言中用來(lái)從 panic 中恢復(fù)的函數(shù)。它只能在 defer 中使用。當(dāng) recover 被調(diào)用時(shí),它會(huì)捕獲到正在執(zhí)行的 panic,并停止 panic 繼續(xù)傳播,恢復(fù)程序的執(zhí)行。

2.1 recover 的使用

recover 會(huì)返回 panic 時(shí)傳遞的值,并恢復(fù)程序的正常執(zhí)行。

如果 recover 沒有在 panic 發(fā)生時(shí)被調(diào)用,panic 會(huì)繼續(xù)向上傳播,直到程序退出。

只有在 defer 函數(shù)內(nèi)部,recover 才能捕獲到 panic。

使用 recover 恢復(fù)程序

func divide(a, b int) int {
	if b == 0 {
		panic("division by zero") // 如果除數(shù)為零,拋出 panic
	}
	return a / b
}

func safeDivide(a, b int) (result int, err string) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Sprintf("Recovered from panic: %v", r)
		}
	}()

	result = divide(a, b) // 可能會(huì)觸發(fā) panic
	return
}

func main() {
	result, err := safeDivide(10, 0)
	if err != "" {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Result:", result)
	}
}
Error: Recovered from panic: division by zero
safeDivide 函數(shù)嘗試執(zhí)行 divide,如果 divide 觸發(fā)了 panic,recover 會(huì)捕獲到并停止 panic 繼續(xù)傳播。

defer 中的匿名函數(shù)通過(guò) recover() 捕獲 panic,并將 panic 的信息作為錯(cuò)誤返回。

程序恢復(fù)執(zhí)行并返回錯(cuò)誤信息,而不會(huì)崩潰。

panic 和 recover 的工作流程

panic 的傳播:

當(dāng) panic 被觸發(fā)時(shí),Go 會(huì)立即停止當(dāng)前函數(shù)的執(zhí)行,并開始遞歸地向上傳播 panic。

每次 panic 傳播時(shí),都會(huì)執(zhí)行當(dāng)前函數(shù)的所有 defer 語(yǔ)句。

recover 捕獲 panic:

如果在某個(gè) defer 語(yǔ)句中調(diào)用 recover,它將會(huì)捕獲當(dāng)前的 panic 并停止 panic 的傳播。

recover 返回 panic 時(shí)傳遞的參數(shù),通常是一個(gè)錯(cuò)誤信息。

如果沒有 recover 捕獲,panic 將繼續(xù)傳播,直到程序退出。

panic 和 recover 使用的注意事項(xiàng)

不要濫用 panic 和 recover:Go 語(yǔ)言的設(shè)計(jì)原則鼓勵(lì)使用顯式的錯(cuò)誤處理機(jī)制(例如返回錯(cuò)誤值),而不是通過(guò) panic 來(lái)表示常規(guī)錯(cuò)誤。panic 應(yīng)該只用于處理那些程序無(wú)法恢復(fù)的錯(cuò)誤(例如數(shù)組越界、無(wú)法恢復(fù)的邏輯錯(cuò)誤等)。

defer 和 recover:recover 必須在 defer 函數(shù)中調(diào)用才能有效。如果 recover 不在 defer 中,它將無(wú)法捕獲到 panic。

panic 和 recover 用于同步代碼:panic 和 recover 通常用于同步函數(shù)的錯(cuò)誤處理。它們不能用于并發(fā)的錯(cuò)誤處理(例如 goroutine 中的錯(cuò)誤處理)。對(duì)于并發(fā)程序,Go 更傾向于通過(guò)返回錯(cuò)誤值來(lái)處理錯(cuò)誤。

panic 和 recover 的機(jī)制引入了較高的開銷,通常應(yīng)避免在高頻調(diào)用的代碼中使用 panic。它們更適合處理那些異常、不可恢復(fù)的錯(cuò)誤,而不是正常的程序流程控制。

實(shí)際應(yīng)用中的使用場(chǎng)景

panic 的場(chǎng)景:當(dāng)程序遇到無(wú)法繼續(xù)執(zhí)行的嚴(yán)重錯(cuò)誤時(shí),調(diào)用 panic。例如:空指針解引用、數(shù)組越界等。

recover 的場(chǎng)景:當(dāng)你希望在程序中捕獲并恢復(fù)某些不可預(yù)見的錯(cuò)誤時(shí),使用 recover。常見的場(chǎng)景包括:Web 服務(wù)器的中間件處理、數(shù)據(jù)庫(kù)事務(wù)的回滾等。

Web 服務(wù)器的 panic 恢復(fù)

func handler(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered from panic:", r)
			http.Error(w, "Internal server error", http.StatusInternalServerError)
		}
	}()

	panic("Something went wrong") // 模擬一個(gè) panic
}


func main() {
	http.HandleFunc("/", handler)
	fmt.Println("Starting server at :8080...")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		fmt.Println("Server failed:", err)
	}
}

服務(wù)器啟動(dòng):當(dāng)你運(yùn)行程序時(shí),main 函數(shù)啟動(dòng) HTTP 服務(wù)器并監(jiān)聽端口 8080。

觸發(fā) panic:當(dāng)你訪問(wèn)根路徑(http://localhost:8080/)時(shí),handler 函數(shù)會(huì)被觸發(fā)。在 handler 函數(shù)中,程序會(huì)故意執(zhí)行 panic("Something went wrong"),模擬一個(gè)錯(cuò)誤的發(fā)生。

recover 捕獲 panic:panic 觸發(fā)后,程序會(huì)立即停止當(dāng)前函數(shù)的執(zhí)行。此時(shí),defer 語(yǔ)句中的匿名函數(shù)被調(diào)用,recover 會(huì)捕獲到 panic,然后通過(guò) http.Error 返回 500 錯(cuò)誤響應(yīng)給客戶端。

恢復(fù)并繼續(xù)執(zhí)行:由于 recover 捕獲并處理了 panic,程序不會(huì)崩潰,而是繼續(xù)執(zhí)行。

到此這篇關(guān)于Go語(yǔ)言中panic和recover的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Go語(yǔ)言 panic和recover內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go Asynq異步任務(wù)處理的實(shí)現(xiàn)

    Go Asynq異步任務(wù)處理的實(shí)現(xiàn)

    Asynq是一個(gè)新興的異步任務(wù)處理解決方案,它提供了輕量級(jí)的、易于使用的API,本文主要介紹了Go Asynq異步任務(wù)處理的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-06-06
  • Go 1.23中Timer無(wú)buffer的實(shí)現(xiàn)方式詳解

    Go 1.23中Timer無(wú)buffer的實(shí)現(xiàn)方式詳解

    在 Go 1.23 中,Timer 的實(shí)現(xiàn)通常是通過(guò) time 包提供的 time.Timer 類型來(lái)實(shí)現(xiàn)的,本文主要介紹了Go 1.23中Timer無(wú)buffer的實(shí)現(xiàn)方式,需要的可以了解下
    2025-03-03
  • GoFrame 框架緩存查詢結(jié)果的示例詳解

    GoFrame 框架緩存查詢結(jié)果的示例詳解

    GoFrame的gdb對(duì)查詢結(jié)果的緩存處理是不是非常的優(yōu)雅。尤其是*gcache.Cache對(duì)象采用了適配器設(shè)計(jì)模式,可以輕松實(shí)現(xiàn)從單進(jìn)程內(nèi)存緩存切換為分布式的Redis緩存,本文重點(diǎn)給大家介紹GoFrame 如何優(yōu)雅的緩存查詢結(jié)果,感興趣的朋友一起看看吧
    2022-06-06
  • 簡(jiǎn)單易用的Go逗號(hào)comma ok模式使用詳解

    簡(jiǎn)單易用的Go逗號(hào)comma ok模式使用詳解

    這篇文章主要為大家介紹了簡(jiǎn)單易用的Go逗號(hào)comma ok模式使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Go語(yǔ)言基礎(chǔ)語(yǔ)法和基本數(shù)據(jù)類型知識(shí)鞏固

    Go語(yǔ)言基礎(chǔ)語(yǔ)法和基本數(shù)據(jù)類型知識(shí)鞏固

    這篇文章主要為大家介紹了Go語(yǔ)言基礎(chǔ)語(yǔ)法和基本數(shù)據(jù)類型知識(shí)鞏固,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • go?defer?return?panic?執(zhí)行順序示例詳解

    go?defer?return?panic?執(zhí)行順序示例詳解

    這篇文章主要介紹了go?defer?return?panic?執(zhí)行順序,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • 如何go語(yǔ)言比較兩個(gè)對(duì)象是否深度相同

    如何go語(yǔ)言比較兩個(gè)對(duì)象是否深度相同

    這篇文章主要介紹了如何go語(yǔ)言比較兩個(gè)對(duì)象是否深度相同,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • go語(yǔ)言中proto文件的使用

    go語(yǔ)言中proto文件的使用

    在Go語(yǔ)言編程中,.proto文件用于定義Protocol?Buffers數(shù)據(jù)結(jié)構(gòu)和服務(wù),是實(shí)現(xiàn)跨語(yǔ)言通信和高效序列化的關(guān)鍵,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-10-10
  • golang解析網(wǎng)頁(yè)利器goquery的使用方法

    golang解析網(wǎng)頁(yè)利器goquery的使用方法

    這篇文章主要給大家介紹了關(guān)于golang解析網(wǎng)頁(yè)利器goquery的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Go1.20?arena新特性示例詳解

    Go1.20?arena新特性示例詳解

    這篇文章主要為大家介紹了Go1.20?arena新特性示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11

最新評(píng)論