日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

一文詳細談談GoLang的panic和error_Golang

作者:渣渣帥 ? 更新時間: 2022-12-29 編程語言

前言

首先說一下:?錯誤指的是可能出現問題的地方出現了問題。如打開件失敗,這種情況在意料之中 。異常指的是不應該出現問題的地方出現了問題。如引用了空指針,這種情況在意料之外

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

欄目分類
最近更新