亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

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

panic 機(jī)制

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

1.1 panic 的使用

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

panic 會導(dǎo)致當(dāng)前函數(shù)的執(zhí)行停止,并且會遞歸地向上層函數(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")

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

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

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

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

recover 機(jī)制

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

2.1 recover 的使用

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

如果 recover 沒有在 panic 發(fā)生時(shí)被調(diào)用,panic 會繼續(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) // 可能會觸發(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 會捕獲到并停止 panic 繼續(xù)傳播。

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

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

panic 和 recover 的工作流程

panic 的傳播:

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

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

recover 捕獲 panic:

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

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

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

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

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

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

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

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

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

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

recover 的場景:當(dāng)你希望在程序中捕獲并恢復(fù)某些不可預(yù)見的錯(cuò)誤時(shí),使用 recover。常見的場景包括:Web 服務(wù)器的中間件處理、數(shù)據(jù)庫事務(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)你運(yùn)行程序時(shí),main 函數(shù)啟動 HTTP 服務(wù)器并監(jiān)聽端口 8080。

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

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

    簡單易用的Go逗號comma ok模式使用詳解

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

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

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

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

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

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

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

    go語言中proto文件的使用

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

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

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

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

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

最新評論