Go語言基礎(四)—— 優質的容錯處理

前言:
本專題用於記錄本身(647)在Go語言方向的學習和積累。 系列內容比較偏基礎,推薦給想要入門Go語言開發者們閱讀。

目錄以下:
Go語言基礎(一)—— 簡介、環境配置、HelloWorld
Go語言基礎(二)—— 基本經常使用語法
Go語言基礎(三)—— 面向對象編程
Go語言基礎(四)—— 優質的容錯處理
Go語言基礎(五)—— 併發編程
Go語言基礎(六)—— 測試、反射、Unsafe
Go語言基礎(七)—— 架構 & 常見任務
Go語言基礎(八)—— 性能調優編程


引子:
Go語言自己沒有try/catch異常機制,由於Go的三位創始人在設計Go語言之出以爲這樣寫會變得很繁瑣。
但由於:Go自己支持函數多返回值,所以在寫函數的時候,能夠優先考慮容錯處理。
安全

接下來,咱們來看看在Go語言中如何作容錯處理。架構

1、Go中的容錯處理

  • 首先,咱們要知道:Go語言中沒有try/catch異常機制。併發

  • 其次,要實現容錯處理:使用error類型便可,默認實現error接口。app

type error interface {
	Error() string
}
複製代碼
  • 經過errors.New快速建立error實例。
var xxxError = errors.New("xxxxx") // 快速建立錯誤類型
複製代碼

接下來舉一個例子:
咱們把以前寫的Fibonacci的例子加上容錯處理,就變成了下面這樣。less

函數添加了多返回值,最後一個返回error。
若error有值,說明有異常;
若error無值,說明程序正常。函數

var LessThanTwoError = errors.New("n shoule not less than 2") // 定義錯誤類型

func GetFibonacci(n int) ([]int, error) {
	// 容錯處理
	if n <= 2 {
		return nil, LessThanTwoError
	}

	fibList := []int{1, 1}
	for i := 2; i < n; i++ {
		fibList = append(fibList, fibList[i-2]+fibList[i-1])
	}
	return fibList, nil
}

func TestGetFibonacci(t *testing.T) {
	if value, err := GetFibonacci(0); err != nil {
		if err == LessThanTwoError {
			fmt.Println("It is less error.")
		}
		t.Error(err)
	} else {
		t.Log(value)
	}
}
複製代碼

2、panic、recover、os.Exit

  • panic:用於發送不可恢復的錯誤,執行defer func內的代碼塊,並請求退出程序。
  • recover:用於恢復panic拋出的錯誤。
  • os.Exit:用於直接退出程序。

咱們舉個簡單的例子:性能

func TestPanic(t *testing.T) {
	defer func() {
		fmt.Println("Finally!")
	}()
	fmt.Println("Test panic is Started.")
	panic(errors.New("Something wrong!"))
}
複製代碼

其實,os.Exit也能夠退出程序。學習

func TestOsExit(t *testing.T) {
	fmt.Println("Test os.Exit is Started.")
	os.Exit(0)
}
複製代碼

問:panicos.Exit究竟有什麼區別呢?
1.os.Exit退出程序時不會先調用defer func代碼塊。
2.os.Exit退出程序時不會輸出當前調用棧信息。測試

那麼,若是咱們就是想讓程序不crash,有沒有辦法呢?

答案是有的,使用recover,可是很不推薦這麼使用recover
由於並無解決發生panic的問題,只是把錯誤移除,這樣是很不安全的。
甚至,若是是由於系統資源panic,這樣咱們的服務就變成了殭屍服務,雖然活着但沒法提供服務功能。

recover使用方式以下,但通常不推薦使用。

func TestPanicRecover(t *testing.T) {
	defer func() {
		if err := recover(); err != nil { // 恢復錯誤
			fmt.Println("recover panic", err)
		}
	}()
	fmt.Println("Test panic is Started.")
	panic(errors.New("Something wrong!"))
}
複製代碼

所以,當心使用recover! 可能會致使:

  1. 造成殭屍服務進程,使安全檢查health check失效。
  2. 由於沒有crash,致使提供不肯定的服務。

所以,須要謹慎使用recover


最後,本系列我是在蔡超老師的技術分享下總結、實戰完成的, 感謝蔡超老師的技術分享

PS:另附上,分享連接:《Go語言從入門到實戰》 祝你們學有所成,工做順利。謝謝!

相關文章
相關標籤/搜索