Go語言 關於go error處理風格的一些討論和個人觀點(下)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

原創文章,轉載請註明出處:伺服器非業餘研究-sunface

 

對於Go來說錯誤如何處理是非常關鍵和重要的,這裡我總結了一些方法可以避免錯誤的錯誤處理機制(具體見關於go error處理風格的一些討論和個人觀點(上))

 

1.錯誤碼常用風格:

以下兩個例子第一個例子明顯好過第二個

f, err := os.Open(path)
if err != nil {
    // handle error
}
// do stuff

 

f, err := os.Open(path)
if err == nil {
    // do stuff
}
// handle error

 

2.自訂錯誤處理風格:

      首先定義錯誤介面:

            type Error string

            func (e Error) Error() string { return string(e) }

      然後用類型斷言判斷錯誤類型

      result, err := yourpackage.Foo()
      if ype, ok := err.(yourpackage.Error); ok {
             // use ype to handle error
      }

      分析檔案,並輸出錯誤資訊:

      type OpenError struct {
             File  *File
             Error string
      }

     func (oe *OpenError) Error() string {
             // format error string here
     }

     func ParseFiles(files []*File) error {
           for _, f := range files {
                 err := f.parse()
                if err != nil {
                   return &OpenError{
                       File:  f,
                       Error: err.Error(),
                   }
               }
           }
     }

     這樣就知道具體哪個檔案在分析的時候失敗了。

     有一點要特別注意:封裝錯誤,因為當你封裝錯誤的時候,原本的錯誤資訊可能會丟失:

      var c net.Conn
      f, err := DownloadFile(c, path)
      switch e := err.(type) {
            case net.Error:
                   // 關閉串連         

                 c.Close()
                 return e
            case error:
                  // error != nil
                  return err

             default:
                 // err == nil的時候會執行這裡

       }
       // do other things.

      如果在這段代碼中你封裝了net.Error,則這段代碼不會再認為是net方面出錯了,也就不會關閉串連,繼續使用之前錯誤的串連。一個比較好的辦法是:當使用外部介面的時候,不要封裝它們產生的錯誤!!

3.錯誤就像狀態一樣:

     有的時候你會暫時不處理一個錯誤,可能因為想延後處理,也可能因為錯誤會很快再出現一次。

     對於第一種情況,bufio就是一個很好的例子,當bufio.Reader遇到一個錯誤的時候,它會持有那個錯誤直到緩衝為空白,才會處理這個錯誤。

     對於第二種情況,go/loader是一個很好的例子,當它被調用且發生錯誤的時候,會持有那個錯誤,因為很可能它會被用相當的參數再調用一次。

 

4.使用函數來避免重複

     如果某種錯誤在不斷重複的出現,就可以使用函數來簡化:

      func handleError(c net.Conn, err error) {
               // 進行錯誤後續處理
      }

      func DoStuff(c net.Conn) error {
              f, err := downloadFile(c, path)
              if err != nil {
                  handleError(c, err)
                  return err
              }
   
             f, err := doOtherThing(c)
             if err != nil {
                 handleError(c, err)
                 return err
             }
       }

      或者可以使用下面這種風格:

func handleError(c net.Conn, err error) {
            if err == nil {
                  return
            }  
    //錯誤後續處理

}

func DoStuff(c net.Conn) error {
    defer func() { handleError(c, err) }()
    f, err := downloadFile(c, path)
    if err != nil {
        return err
    }
   
    f, err := doOtherThing(c)
    if err != nil {
        return err
    }
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.