Golang全面深入系列之 Error

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

What you are wasting today is tomorrow for those who died yesterday; what you hate now is the future you can not go back.

你所浪費的今天是昨天死去的人奢望的明天; 你所厭惡的現在是未來的你回不去的曾經。

 

Go errors簡介

    在Go的慣用法中,傳回值不是整型等常用傳回值類型,而是用了一個 error(interface類型)。

// The error built-in interface type is the conventional interface for// representing an error condition, with the nil value representing no error.type error interface {Error() string}

就像任何其他內建類型,如int,float64一樣......錯誤值可以儲存在變數中,從函數返回等等。

ackage mainimport (      "fmt"    "os")func main() {      f, err := os.Open("/test.txt")    if err != nil {        fmt.Println(err)        return    }    fmt.Println(f.Name(), "opened successfully")}

如果檔案test.txt不存在, Open方法會返回error.

在go中處理錯誤的慣用方式是將返回的錯誤與nil進行比較。零值表示沒有發生錯誤,而非零值表示存在錯誤。在上面的例子中,我們檢查錯誤是否不為nil。如果不是,我們只需列印錯誤並從主函數返回。

 

錯誤類型定義

type error interface {      Error() string}

我們知道,golang中 error的定義是一個介面類型, 任何實現此介面的類型都可以用作錯誤的輸出調用。此方法提供錯誤的描述。當列印錯誤時,fmt.println函數在內部調用Error()字串方法來擷取錯誤的描述。

 

從錯誤中提取更多資訊的不同方式

    現在我們知道error是一種介面類型,可以讓我們看看如何提取更多有關的錯誤資訊。例如:上面例子中,我們想提取導致錯誤的檔案路徑該如何擷取?

1.聲明底層結構類型並從結構欄位擷取更多資訊

如果仔細閱讀open函數的文檔,可以看到它返回了類型*Patherror的錯誤。Patherror是一個結構類型

Open方法的實現:

func Open(name string) (*File, error) {return OpenFile(name, O_RDONLY, 0)}

OpenFile方法的實現:

// OpenFile is the generalized open call; most users will use Open// or Create instead. It opens the named file with specified flag// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,// methods on the returned File can be used for I/O.// If there is an error, it will be of type *PathError.func OpenFile(name string, flag int, perm FileMode) (*File, error) {if name == "" {return nil, &PathError{"open", name, syscall.ENOENT}}r, errf := openFile(name, flag, perm)if errf == nil {return r, nil}r, errd := openDir(name)if errd == nil {if flag&O_WRONLY != 0 || flag&O_RDWR != 0 {r.Close()return nil, &PathError{"open", name, syscall.EISDIR}}return r, nil}return nil, &PathError{"open", name, errf}}

其中發生錯誤都返回了*PathError這個結構體執行個體。那麼我們來看看這個結構體的具體資訊。

// PathError records an error and the operation and file path that caused it.type PathError struct {Op   stringPath stringErr  error}func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }

此結構體實現了error介面。 結構體元素中也包括了Path的相關資訊。

那麼我們修改一上樣本的代碼:

package mainimport ("fmt""os")func main() {f, err := os.Open("/test.txt")if errObject, ok := err.(*os.PathError); ok {fmt.Println("錯誤輸出:",err, "檔案路徑:", errObject.Path)return}fmt.Println(f.Name(), "opened successfully")}

此時的errObject就是PathError的一個執行個體。

現在,我們已成功使用類型斷言來從錯誤中擷取檔案路徑。

2.聲明底層結構類型並使用方法擷取更多資訊

通過調用結構類型的方法來斷言底層類型並擷取更多資訊。

讓我們通過一個例子來更好地理解這一點。標準庫中的DNSError結構類型定義如下,

type DNSError struct {      ...}func (e *DNSError) Error() string {      ...}func (e *DNSError) Timeout() bool {      ... }func (e *DNSError) Temporary() bool {      ... }

從上面的代碼可以看出,DNSError結構有兩個方法timeout()bool和temporary()bool,它們返回一個布爾值,表示錯誤是由於逾時還是臨時性的。

package mainimport ("fmt""net")func main() {addr, err := net.LookupHost("wwwwwwwwww.xxxx")if err, ok := err.(*net.DNSError); ok {if err.Timeout() {fmt.Println("operation timed out")} else if err.Temporary() {fmt.Println("temporary error")} else {fmt.Println("generic error: ", err)}return}fmt.Println(addr)}

程式會輸出:generic error:  lookup wwwwwwwwww.xxxx: no such host,  我們就可以確定錯誤既不是暫時性的,也不是由於逾時。

3.直接比較

package mainimport (      "fmt"    "path/filepath")func main() {      files, error := filepath.Glob("[")    if error != nil && error == filepath.ErrBadPattern {        fmt.Println(error)        return    }    fmt.Println("matched files", files)}

如果Glob()的模式錯誤,就會報ErrBadPattern的錯誤類型。

最後一點:

 

永遠不要忽略錯誤

記住!!!多寫一點小麻煩,省掉千千萬萬個大麻煩!!!

 

最後,寫的有點匆忙,有錯誤之處還望指正!

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.