Go語言中的recover()函數(shù)用法解讀
recover()
是 Go 語言中用于處理 panic 的內(nèi)置函數(shù),它允許程序管理發(fā)生 panic 的 goroutine 的行為。
下面我將詳細(xì)解釋它的工作原理和使用方法。
基本概念
1. 函數(shù)簽名
func recover() any
2. 核心功能
recover()
可以:
- 停止 panic 的傳播
- 返回傳遞給
panic()
的值 - 恢復(fù)正常的程序執(zhí)行
工作原理
1. 使用位置
recover()
必須在 defer 函數(shù)中直接調(diào)用才有效:
defer func() { if r := recover(); r != nil { // 處理 panic } }()
2. 返回值
- 當(dāng) goroutine 正在 panic 且在 defer 函數(shù)中調(diào)用時(shí):返回傳遞給
panic()
的值 - 其他情況(包括 panic 參數(shù)為 nil 的情況,Go 1.21 之前):返回 nil
使用示例
基本用法
func mayPanic() { panic("something went wrong") } func main() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered from panic:", r) } }() mayPanic() fmt.Println("This will not be executed if panic occurs") }
輸出:Recovered from panic: something went wrong
實(shí)際應(yīng)用場景
func safeDivide(a, b int) (result int, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("runtime error: %v", r) } }() return a / b, nil }
重要特性
必須與 defer 配合使用:只有在 defer 函數(shù)中直接調(diào)用才有效
作用域限制:只能恢復(fù)同一個(gè) goroutine 中的 panic
Go 1.21 的變化:
- 之前版本:
panic(nil)
時(shí)recover()
返回 nil - Go 1.21+:
panic(nil)
會引發(fā) runtime panic,recover()
返回*runtime.PanicNilError
注意事項(xiàng)
- 不要濫用 recover:應(yīng)該只用于處理真正的意外情況,而不是替代常規(guī)錯(cuò)誤處理
- 資源清理:即使 panic 被 recover,defer 函數(shù)仍然會執(zhí)行
- 跨 goroutine:無法恢復(fù)其他 goroutine 的 panic
- 性能影響:panic/recover 比常規(guī)錯(cuò)誤處理機(jī)制性能差
與 panic 的關(guān)系
recover()
和 panic()
是配套使用的:
func doSomething() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered:", r) } }() if somethingWrong { panic("critical error") } }
最佳實(shí)踐
- 為關(guān)鍵代碼段添加 recover
- 記錄 recover 到的錯(cuò)誤信息
- 盡量讓程序在 recover 后能繼續(xù)正常運(yùn)行
- 避免在庫函數(shù)中靜默地 recover 而不返回錯(cuò)誤
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Go數(shù)據(jù)庫遷移的實(shí)現(xiàn)步驟
本文主要介紹了Go數(shù)據(jù)庫遷移的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Go 微服務(wù)開發(fā)框架DMicro設(shè)計(jì)思路詳解
這篇文章主要為大家介紹了Go 微服務(wù)開發(fā)框架DMicro設(shè)計(jì)思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10go語言中嵌套結(jié)構(gòu)體的實(shí)現(xiàn)
在Go語言中,嵌套結(jié)構(gòu)體可定義為一個(gè)結(jié)構(gòu)體內(nèi)包含另一個(gè)結(jié)構(gòu)體,嵌套可以是值嵌套或指針嵌套,兩者在內(nèi)存分配和修改影響上有顯著區(qū)別,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下2024-09-09Golang 端口復(fù)用測試的實(shí)現(xiàn)
這篇文章主要介紹了Golang 端口復(fù)用測試的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Golang并發(fā)編程之main goroutine的創(chuàng)建與調(diào)度詳解
這篇文章主要為大家詳細(xì)介紹了Golang并發(fā)編程中main goroutine的創(chuàng)建與調(diào)度,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03利用Go語言實(shí)現(xiàn)流量回放工具的示例代碼
今天給大家推薦一款使用Go語言編寫的流量回放工具?--?goreplay;工作中你一定遇到過需要在服務(wù)器上抓包的場景,有了這個(gè)工具就可以助你一臂之力,廢話不多,我們接下來來看一看這個(gè)工具2022-09-09在Go中動(dòng)態(tài)替換SQL查詢中的日期參數(shù)的完整步驟
在處理數(shù)據(jù)庫查詢時(shí),經(jīng)常需要根據(jù)不同的輸入條件動(dòng)態(tài)地構(gòu)造SQL語句,尤其是在涉及日期范圍的查詢中,能夠根據(jù)實(shí)際需求調(diào)整查詢的起始和結(jié)束日期顯得尤為重要,在本文中,我將介紹如何在Go語言中實(shí)現(xiàn)動(dòng)態(tài)替換SQL查詢中的日期參數(shù),需要的朋友可以參考下2024-11-11