GoLang之錯誤處理

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

 

 

錯誤處理

 

error

Go語言引入了一個錯誤處理的標準模式,即error介面,該介面定義如下:

type error interface {    Error() string}

 

對於大多數函數,如果要返回錯誤,可以將error作為多傳回值的最後一個:

func foo(param int)(ret int, err error){  ...  }

 

調用時的代碼:

n, err := foo(0)if err != nil {    //  錯誤處理} else {    // 使用傳回值n}

 

我們還可以自訂錯誤類型,一個例子:

package main import "fmt"import "errors" //自訂的出錯結構type myError struct {    arg  int    errMsg string}//實現Error介面func (e *myError) Error() string {    return fmt.Sprintf("%d - %s", e.arg, e.errMsg)} //兩種出錯func error_test(arg int) (int, error) {    if arg < 0  {         return -1, errors.New("Bad Arguments - negtive!")     }else if arg >256 {        return -1, &myError{arg, "Bad Arguments - too large!"}    }    return arg*arg, nil} //相關的測試func main() {    for _, i := range []int{-1, 4, 1000} {        if r, e := error_test(i); e != nil {            fmt.Println("failed:", e)        } else {            fmt.Println("success:", r)        }    }}

 

 

 

defer 

你可以在Go函數中添加多個defer語句,當函數執行到最後時,這些defer語句會按照逆序執行(即最後一個defer語句將最先執行),最後該函數返回。

特別是當你在進行一些開啟資源的操作時,遇到錯誤需要提前返回,在返回前你需要關閉相應的資源,不然很容易造成資源流失等問題。如下代碼所示,我們一般寫開啟一個資源是這樣操作的:

func CopyFile(dst, src string) (w int64, err error) {    srcFile, err := os.Open(src)    if err != nil {        return     }    defer srcFile.Close()    dstFile, err := os.Create(dst)    if err != nil {        return     }    defer dstFile.Close()    return io.Copy(dstFile, srcFile)}

 

如果defer後面一條語句幹不完清理工作,也可以使用一個匿名函數:

defer func(){    ...}()

 


注意,defer語句是在return之後執行的,例如:

func test() (result int) {    defer func() {        result = 12    }()    return 10}func main() {    fmt.Println(test())     // 12}

 

 

panic() recover()

panic()函數用於拋出異常,recover()函數用於捕獲異常,這兩個函數的原型如下:

func panic(interface{})func recover() interface{}

 

當在一個函數中調用panic()時,正常的函數執行流程將立即終止,但函數中之前使用defer關鍵字順延強制的語句將正常展開執行,之後該函數將返回到調用函數,並導致逐層向上執行panic()流程,直至所屬的goroutine中所有正在執行的函數被終止。錯誤資訊將被報告,包括在調用panic()函數時傳入的參數,這個過程稱為錯誤流程處理。

panic()接受一個interface{}參數,可支援任意類型,例如:

panic(404)panic("network broken")panic(Error("file not exists"))

 

在defer語句中,可以使用recover()終止錯誤處理流程,這樣可以避免異常向上傳遞,但要注意recover()之後,程式不會再回到panic()那裡,函數仍在defer之後返回。


func foo() { panic(errors.New("i'm a bug")) return}func test() (result int) { defer func() { if r := recover(); r != nil { err := r.(error) fmt.Println("Cache Exception:", err) } }() foo() return 10}func main() { fmt.Println(test()) // 0}

 

 

 

 

 

注意,在一個函數中panic被調用後,其defer語句仍會執行,

func foo()(n int) {    defer func() {        if r := recover(); r != nil {            n++    // take effective        }    }()    n++             // take effective    panic(errors.New("i'm a bug"))    n++             // take no effective    return n}

 

聯繫我們

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