溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go語言的錯誤處理方式是什么

發(fā)布時間:2022-04-14 16:10:03 來源:億速云 閱讀:160 作者:iii 欄目:編程語言

這篇文章主要介紹了Go語言的錯誤處理方式是什么的相關知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Go語言的錯誤處理方式是什么文章都會有所收獲,下面我們一起來看看吧。

構造 error

在 go 語言中,有一個預定義的接口:error,該接口自帶一個 Error() 方法,調(diào)用該方法會返回一個字符串。

type error interface {   Error() string }

調(diào)用該方法,會返回當前錯誤的具體結果。一般有下面幾種方式生成 error。

  • errors.New()

  • fmt.Errorf()

errors.New()

調(diào)用 errors.New() 會返回一個 error 類型的結構體,該結構體內(nèi)部會實現(xiàn)一個 Error() 方法, 調(diào)用該方法返回的結果為調(diào)用  errors.New() 方法時傳入的內(nèi)容。

import (  "errors"  "fmt" )  func divide(a, b int) (error, int) {  if b == 0 {     // 被除數(shù)為0,則構造一個 error 結構體   return errors.New("被除數(shù)不能為0"), 0  }  var result = a / b  return nil, result }  func main() {  var err error // error 類型數(shù)據(jù)的初始值為 nil,類似于 js 中的 null  var result int   err, result = divide(1, 0)    if err == nil {     // 如果 err 為 nil,說明運行正常     fmt.Println("計算結果", result)   } else {     // 如果 err 不為 nil,說明運行出錯     // 調(diào)用 error 結構體的 Error 方法,輸出錯誤原因     fmt.Println("計算出錯", err.Error())   } }

可以看到,上面的代碼中,由于調(diào)用 divide 除法方法時,由于傳入的被除數(shù)為 0。經(jīng)過判斷,會拋出一個由 errors.New 構造的 error  類型的結構體。

我們將調(diào)用 error.Error() 方法返回的結果輸出到控制臺,可以發(fā)現(xiàn)其返回的結果,就是傳入 New 方法的值。

執(zhí)行結果如下:

Go語言的錯誤處理方式是什么

fmt.Errorf()

通過 fmt.Errorf() 方法構造的 error 結構體,與調(diào)用 errors.New() 方法的結果類似。不同的是,fmt.Errorf()  方法會進行一次數(shù)據(jù)的格式化。

func divide(a, b int) (error, int) {  if b == 0 {     // 將參數(shù)進行一次格式化,格式化后的字符串放入 error 中   return fmt.Errorf("數(shù)據(jù) %d 不合法", b), 0  }  var result = a / b  return nil, result }  err, result := divide(1, 0) fmt.Println("計算出錯", err.Error())

執(zhí)行結果如下:

Go語言的錯誤處理方式是什么

panic() 與 recover()

panic()

panic() 相當于主動停止程序運行,調(diào)用時 panic()  時,需要傳入中斷原因。調(diào)用后,會在控制臺輸出中斷原因,以及中斷時的調(diào)用堆棧。我們可以改造一下之前的代碼:

func divide(a, b int) (error, int) {  if b == 0 {     // 如果程序出錯,直接停止運行   panic("被除數(shù)不能為0")  }  var result = a / b  return nil, result }  func main() {   err, result := divide(1, 0)   fmt.Println("計算出錯", err.Error()) }

在運行到 panic() 處,程序直接中斷,并在控制臺打印出了中斷原因。

Go語言的錯誤處理方式是什么

panic() 可以理解為,js 程序中的 throw new Error() 的操作。那么,在 go 中有沒有辦法終止 panic() ,也就是類似于  try-catch 的操作,讓程序回到正常的運行邏輯中呢?

recover()

在介紹 recover() 方法之前,還需要介紹一個 go 語言中的另一個關鍵字:defer。

defer 后的語句會在函數(shù)進行 return 操作之前調(diào)用,常用于資源釋放、錯誤捕獲、日志輸出。

func getData(table, sql) {   defer 中斷連接()   db := 建立連接(table)   data := db.select(sql)   return data }

defer 后的語句會被存儲在一個類似于棧的數(shù)據(jù)結構內(nèi),在函數(shù)結束的時候,被定義的語句按順序出棧,越后面定義的語句越先被調(diào)用。

func divide(a, b int) int {   defer fmt.Println("除數(shù)為", b)   defer fmt.Println("被除數(shù)為", a)    result := a / b   fmt.Println("計算結果為", result)  return result }  divide(10, 2)

上面的代碼中,我們在函數(shù)開始運行的時候,先通過 defer 定義了兩個輸出語句,先輸出除數(shù),后輸出被除數(shù)。

Go語言的錯誤處理方式是什么

實際的運行結果是:

  • 先輸出計算結果;

  • 然后輸出被除數(shù);

  • 最后輸出除數(shù);

這和前面提到的,通過 defer 定義的語句會在函數(shù)結束的時候,按照出棧的方式進行執(zhí)行,先定義的后執(zhí)行。defer  除了會在函數(shù)結束的時候執(zhí)行,出現(xiàn)異常的的時候也會先走 defer 的邏輯,也就是說,我們在調(diào)用了 panic() 方法后,程序中斷過程中,也會先將 defer  內(nèi)的語句運行一遍。

這里我們重新定義之前的 divide 函數(shù),在執(zhí)行之前加上一個 defer 語句,defer 后面為一個自執(zhí)行函數(shù),該函數(shù)內(nèi)會調(diào)用 recover()  方法。

Go語言的錯誤處理方式是什么

recover() 方法調(diào)用后,會捕獲到當前的 panic() 拋出的異常,并進行返回,如果沒有異常,則返回 nil。

func divide(a, b int) int {   // 中斷之前,調(diào)用 defer 后定義的語句  defer func() {   if err := recover(); err != nil {    fmt.Println("捕獲錯誤", err)   }  }()   if b == 0 {     // 函數(shù)運行被中斷   panic("被除數(shù)不能為0")   return 0  }   return a / b }  result := divide(1, 0) fmt.Println("計算結果", result)

上面的代碼運行后,我們發(fā)現(xiàn)之前調(diào)用 panic() 中斷的程序被恢復了,而且后面的計算結果也正常進行輸出了。

Go語言的錯誤處理方式是什么

這就有點類似于 try-catch 的邏輯了,只是 recover 需要放在 defer 關鍵詞后的語句中,更像是 catch 和 finally  的結合。

關于“Go語言的錯誤處理方式是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Go語言的錯誤處理方式是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI