iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
Modern Web

golang後端入門分享系列 第 19

Day19-Go錯誤處理(下)

前言

在昨天的文章,帶來簡單的錯誤處理運用,今天要帶來較為實務上的運
Go 語言本身沒有例外處理機制,而是以 defer、panic、recover 取而代之,用來滿足錯誤處理的需求。

defer延遲執行

在 Go 語言中,可以使用 defer 來使某個韓式達到延遲的效果,我們來看一下這個所謂延遲的效果:

package main
 
import (
   "fmt"
)
 
func main() {
   defer fmt.Println(1)
   fmt.Println(2)
}

上述的程式碼會先印出2,在印出1,這是就是延遲的效果,在 main function 中,在最後 return 前,執行 defer 後的程式碼。

那如果有多個函式被冠上 defer 呢?我們看下列的程式碼:

package main
 
import (
   "fmt"
)
 
func main() {
   defer fmt.Println(1)
   defer fmt.Println(2)
   fmt.Println(3)
}

這樣印出來的順序為3、2、1,所以我們得知,印出的順序跟 defer 的順序相反,也就是第一個 defer,會最後一個執行。

panic錯誤恐慌

使用 panic 會導致系統崩潰和服務中斷,所以 panic 會使用在發生較重大錯誤的時候,我們這裡稍微將昨天程式更改一下:

package main
import (
  "fmt"
  "strconv"
)
func main() {
  i, err := strconv.Atoi("0.5")
  if err != nil {
      panic("crash")
      fmt.Println("couldn't convert number:", err)
  }
  fmt.Println("Converted integer:", i)
}

在執行 ㄏ後會產生裡面的錯誤訊息,且不會執行後面的程式碼,來看看他輸出的結果:

panic: crash

其實這個例子只是簡單舉例 panic 的作用,在你自己的服務中,什麼時候要使用到 panic,需要自己評估。

recover捕獲錯誤

Go 語言中沒有try-catch這類的捕捉語法,但提供 recover 可以捕捉到 panic 拋擲錯誤,以回復系統以避免程序崩潰。因為 defer 在程式碼最後必執行的特性,recover 必須和 defer 配合使用,如下:

package main
 
import (
   "fmt"
   "strconv"
)
 
func main() {
   i, err := strconv.Atoi("0.5")
 
   defer func() {
       if err := recover(); err != nil {
           fmt.Println("couldn't convert number:", err)
       }
   }()
 
   if err != nil {
       panic("crash")
   }
 
   fmt.Println("Converted integer:", i)
}

在執行 panic 後系統並無直接崩潰,而是繼續執行 recover 後面的程式碼,但一樣,在 panic 後的程式碼是不會被執行的。

結語

今天介紹 defer、panic、recover 三者的使用方式,而在使用上,需考慮到自己的需求。Go 語言中,使用 error 的話,可以明確地進行錯誤檢查;而使用 panic 會比較便於傳播錯誤,建議搭配 recover 使用以捕捉錯誤,並轉換成 error。


上一篇
Day18-Go錯誤處理(上)
下一篇
Day20-Go測試(testing)
系列文
golang後端入門分享30

尚未有邦友留言

立即登入留言