程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> golang錯誤處理之error

golang錯誤處理之error

編輯:JAVA綜合教程

golang錯誤處理之error


golang中沒有try/catch這樣的異常處理機制,只能依靠返回值來做狀態是否出錯判斷(當然它有個panic/recover機制,但一般只處理意想不到的錯誤)。

對於函數的返回值,慣例是最後一個參數返回error對象,來表示函數運行的狀態。
如:
  1. n, err := func()
  2. if err != nil {
  3. ...//process error
  4. }
或者寫在一起
  1. if n, err := func(); err != nil {
  2. ...//process error
  3. }

error對象可以由errors.New()或fmt.Errorf()構造。
如:
  1. var dividedErr = errors.New("Cant divided by 0")

  1. err := fmt.Errorf("%d cant divided by 0", arg)

我們先來看看error到底是什麼類型。
error在標准庫中被定義為一個接口類型,該接口只有一個Error()方法:
  1. type error interface {
  2. Error() string
  3. }
也就是說,自定義的結構只需要擁有Error()方法,就相當於實現了error接口。


我們可以創建一個結構體,並實現Error()方法,就能根據自己的意願構造error對象了。
如:
  1. type division struct {
  2. arg int
  3. str string
  4. }
  5. func (e *division) Error() string {
  6. return fmt.Sprintf("%d %s", e.arg, e.str)
  7. }
  8. func divideCheck(arg1, arg2 int) (error) {
  9. if arg2 == 0 {
  10. return &division{arg1, "can't divided by 0"}
  11. }
  12. return nil
  13. }

再來看一個例子,檢查一組數據中是否有不能除(即除數為0)的情況,如果有則返回出錯。
代碼如下:
  1. package main
  2. import "fmt"
  3. func divideCheck(arg1, arg2 int) (error) {
  4. if arg2 == 0 {
  5. return fmt.Errorf("%d can't divided by 0", arg1)
  6. }
  7. return nil
  8. }
  9. func main() {
  10. var err error
  11. err = divideCheck(4, 2)
  12. if err != nil {
  13. fmt.Println(err)
  14. return
  15. }
  16. err = divideCheck(8, 0)
  17. if err != nil {
  18. fmt.Println(err)
  19. return
  20. }
  21. }

我們實現了這個功能,但是這樣的代碼非常不優雅,每執行一次函數調用都至少要用3行來做錯誤處理。

下面來優化一下。我們需要實現的功能是,只要有一個數不能除,就返回出錯。那麼只需要把每次檢查後的狀態存儲到內部狀態變量裡,在全部處理完成後再檢查這個變量就行了。
代碼如下:
  1. package main
  2. import "fmt"
  3. type division struct {
  4. err error
  5. }
  6. func (this *division)DivideCheck(arg1, arg2 int) {
  7. if this.err != nil {
  8. return
  9. }
  10. if arg2 == 0 {
  11. this.err = fmt.Errorf("%d can't divided by 0", arg1)
  12. return
  13. }
  14. }
  15. func (this *division)Err() error {
  16. return this.err
  17. }
  18. func main() {
  19. d := new(division)
  20. d.DivideCheck(4, 2)
  21. d.DivideCheck(8, 0)
  22. if d.Err() != nil {
  23. fmt.Println(d.Err())
  24. }
  25. }
這麼做代碼就優雅多了,並且在每次檢查前都判斷內部狀態是否已經出錯,出錯就馬上返回,幾乎沒有性能損失。


golang的錯誤處理是經常被诟病的地方,但如果懂得以go的方式編程,還是可以做的挺優雅的~

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved