網站首頁 編程語言 正文
前言
首先說一下:?錯誤指的是可能出現問題的地方出現了問題。如打開件失敗,這種情況在意料之中 。異常指的是不應該出現問題的地方出現了問題。如引用了空指針,這種情況在意料之外
Go
?提供兩種錯誤處理方式
- 函數返回?
error
?類型對象判斷錯誤 -
panic
?異常
1. panic
Go的類型系統會在編譯時捕獲很多錯誤,但有些錯誤只能在運行時檢查,如數組訪問越界、空指針引用等。這些運行時錯誤會引起painc異常。
一般而言,當panic異常發生時,程序會中斷運行,并立即執行在該goroutine(可以先理解成線程)中被延遲的函數(defer 機制)。隨后,程序崩潰并輸出日志信息。日志信息包括panic value和函數調用的堆棧跟蹤信息。panic value通常是某種錯誤信息。對于每個goroutine,日志信息中都會有與之相對的,發生panic時的函數調用堆棧跟蹤信息。通常,我們不需要再次運行程序去定位問題,日志信息已經提供了足夠的診斷依據。因此,在我們填寫問題報告時,一般會將panic異常和日志信息一并記錄。不是所有的panic異常都來自運行時,直接調用內置的panic函數也會引發panic異常;panic函數接受任何值作為參數。當某些不應該發生的場景發生時,我們就應該調用panic。雖然Go的panic機制類似于其他語言的異常,但panic的適用場景有一些不同。由于panic會引起程序的崩潰,因此panic一般用于嚴重錯誤,如程序內部的邏輯不一致。
panic
可以手工調用,但是?Go
?官方建議盡量不要使用panic
,每一個異常都應該用?error
?對象捕獲。如果異常出現了,但沒有被捕獲并恢復,Go
?程序的執行就會被終止,即便出現異常的位置不在主?Goroutine
?中也會這樣。
總結來說:
panic是一個嚴重錯誤機制,它會導致程序終止,并依次逆序執行 panic 所在函數可能存在的 defer 函數列表,然后返回該函數的調用方。recover 內置函數可用于捕獲 panic,重新恢復程序正常執行流程,但是 recover 函數只有在 defer 內部使用才有效
此外,當?panic()
?觸發的宕機發生時,?panic()
?后面的代碼將不會被運行,但是在?panic()
?函數前面已經運行過的?defer
?語句依然會在宕機發生時發生作用
2. recover
1. recover
?是一個?Go
?語言的內建函數,可以讓進入宕機流程中的?goroutine
?恢復過來。
2. 用來控制一個goroutine的panicking行為,捕獲panic,從而影響應用的行為
3. 一般的調用建議
a). 在defer函數中,通過recever來終止一個gojroutine的panicking過程,從而恢復正常代碼的執行
b). 可以獲取通過panic傳遞的error
簡單來講:go中可以拋出一個panic的異常,然后在defer中通過recover捕獲這個異常,然后正常處理。
4.?在正常的執行過程中,調用?recover
?會返回?nil
?并且沒有其他任何效果;
注意:利用recover處理panic指令,defer必須在panic之前聲明,否則當panic時,recover無法捕獲到panic.
總結來說?Go
?語言沒有異常系統,其使用?panic
?觸發宕機類似于其他語言的拋出異常,?recover
?的宕機恢復機制就對應其它語言中的?try/catch
?機制。
panic 和 recover 的關系
panic 和 recover 的組合有如下特性:
有 panic 沒 recover ,程序宕機。
有 panic 也有 recover ,程序不會宕機,執行完對應的 defer 后,從宕機點退出當前函數后繼續執行。
注意:在 panic 觸發的 defer 函數內,可以繼續調用 panic ,進一步將錯誤外拋,直到程序整體崩潰。如果想在捕獲錯誤時設置當前函數的返回值,可以對返回值使用命名返回值方式直接進行設置。
示例:
package main func test() { defer func() { if err := recover(); err != nil { // recover 捕獲錯誤。 println(err.(string)) // 將 interface{} 轉型為具體類型。 } }() panic("panic error!") // panic 拋出錯誤 } func main() { test() }
3. error
go中的錯誤處理,是通過返回值的形式來出來,要么你忽略,要么你處理(處理也可以是繼續返回給調用者),對于golang這種設計方式,我們會在代碼中寫大量的if判斷,以便做出決定。
對于err如果是nil就代表沒有錯誤,如果不是nil就代表程序出問題了,需要對錯誤進行處理了。
示例:
func main() { conent,err:=ioutil.ReadFile("filepath") if err !=nil{ //錯誤處理 }else { fmt.Println(string(conent)) } }
此外,error類型是go語言的一種內置類型,使用的時候不用特定去import,他本質上是一個接口,
type error interface{ Error() string //Error()是每一個訂制的error對象需要填充的錯誤消息,可以理解成是一個字段Error }
總結
原文鏈接:https://blog.csdn.net/qq_39458487/article/details/124798684
相關推薦
- 2022-06-18 C#讀寫Config配置文件案例_C#教程
- 2023-08-13 什么是單點登錄?
- 2022-06-02 Docker部署項目完全使用指南(小結)_docker
- 2022-04-26 jQuery實現鎖定頁面元素(表格列)_jquery
- 2022-04-30 C語言使用鏈表實現學生籍貫管理系統_C 語言
- 2023-12-15 Linux系統設置多個IP地址、默認路由、指定路由、永久刪除默認路由
- 2022-06-16 Python中弱引用的神奇用法與原理詳解_python
- 2023-04-10 基于Python實現錄音功能的示例代碼_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支