深入理解Go語言中defer和panic的執(zhí)行順序
簡介
在 Go 語言中,defer 和 panic 的執(zhí)行順序是一個重要的概念。本文將通過一個示例代碼來詳細(xì)解釋為什么 defer 中的代碼會先執(zhí)行,而 panic 的錯誤信息稍后才輸出。
示例代碼
package main
import "fmt"
func mayPanic() {
panic("a problem")
}
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered. Error:\n", r)
}
}()
mayPanic()
fmt.Println("After mayPanic()")
}執(zhí)行順序解釋
1. defer 的執(zhí)行機制
defer 的作用是延遲執(zhí)行一個函數(shù)調(diào)用,直到包含它的函數(shù)執(zhí)行完畢。無論函數(shù)是正常結(jié)束還是因為錯誤(如 panic)結(jié)束,所有被 defer 延遲的函數(shù)都會按照后進(jìn)先出(LIFO)的順序執(zhí)行。
2. panic 的傳播機制
當(dāng) panic 被觸發(fā)時,Go 會立即中斷當(dāng)前函數(shù)的正常執(zhí)行流程,并開始向上層調(diào)用棧傳播錯誤信號。在這個過程中,Go 會依次執(zhí)行當(dāng)前函數(shù)中所有被 defer 延遲的函數(shù)。這些延遲函數(shù)可以通過 recover() 捕獲并處理 panic。
3. 代碼執(zhí)行順序
(1) 執(zhí)行 main() 函數(shù)
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered. Error:\n", r)
}
}()
mayPanic() // 觸發(fā) panic
fmt.Println("After mayPanic()") // 這行代碼不會執(zhí)行
}(2) 調(diào)用 mayPanic()
func mayPanic() {
panic("a problem")
}panic("a problem") 被觸發(fā),程序會立即中斷當(dāng)前函數(shù)的執(zhí)行,并將 panic 信息傳播到上層調(diào)用棧。
(3) 觸發(fā) defer 延遲函數(shù)
由于 panic 的觸發(fā),Go 會開始執(zhí)行 main() 函數(shù)中被 defer 延遲的函數(shù):
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered. Error:\n", r)
}
}()在這個延遲函數(shù)中,recover() 被調(diào)用,捕獲了 panic 的錯誤信息 "a problem",并打印出來。
(4) panic 被恢復(fù)
由于 recover() 成功捕獲了 panic,程序的正常執(zhí)行流程得以恢復(fù)。不過,panic 的傳播已經(jīng)中斷了 main() 函數(shù)的正常執(zhí)行,因此 fmt.Println("After mayPanic()") 不會執(zhí)行。
4. 輸出結(jié)果順序
按照以上執(zhí)行順序,程序的輸出如下:
Recovered. Error: a problem
為什么 defer 先執(zhí)行?
這是因為 panic 的傳播機制會觸發(fā)所有 defer 延遲函數(shù)的執(zhí)行。defer 的設(shè)計初衷是確保某些重要的清理操作(如釋放資源、關(guān)閉文件等)能夠在函數(shù)結(jié)束時執(zhí)行,即使函數(shù)是因 panic 而異常結(jié)束的。
總結(jié)來說:
panic會中斷當(dāng)前函數(shù)的執(zhí)行。Go 會依次執(zhí)行所有被
defer延遲的函數(shù)。recover()可以在延遲函數(shù)中捕獲panic并恢復(fù)程序的執(zhí)行。
總結(jié)
通過上述代碼和解釋,我們可以清楚地看到 defer 和 panic 的執(zhí)行順序是由 Go 語言的設(shè)計規(guī)則決定的。defer 確保了清理操作的執(zhí)行,而 panic 的傳播機制允許我們在延遲函數(shù)中捕獲并處理錯誤。
到此這篇關(guān)于Go語言中defer和panic的執(zhí)行順序的文章就介紹到這了,更多相關(guān)Go語言 defer和panic執(zhí)行順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang中實現(xiàn)數(shù)據(jù)脫敏處理的go-mask包分享
這篇文章主要是來和大家分享一個在輸出中對敏感數(shù)據(jù)進(jìn)行脫敏的工作包:go-mask,可以將敏感信息輸出的時候替換成星號或其他字符,感興趣的小編可以跟隨小編一起了解下2023-05-05
k8s容器互聯(lián)flannel?vxlan通信原理
這篇文章主要為大家介紹了k8s容器互聯(lián)flannel?vxlan通信原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
如何使用?Go?和?Excelize?構(gòu)建電子表格
這篇文章主要介紹了如何使用Go和Excelize構(gòu)建電子表格,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09

