這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Go中有一個名為error的內建介面,定義如下:
type error interface {
Error() string }
Go是使用一個獨立的·明確的傳回值來傳遞錯誤資訊的。這與使用異常的 Java 和 Ruby 以及在 C 語言中經常見到的超重的單傳回值/錯誤值相比,Go 語言的處理方式能清楚的知道哪個函數返回了錯誤,並能想調用那些沒有出錯的函數一樣調用。 看一段實驗樓的代碼:
package mainimport "errors"import "fmt"// 按照慣例,錯誤通常是最後一個傳回值並且是 `error` 類// 型,一個內建的介面。func f1(arg int) (int, error) { if arg == 42 { // `errors.New` 構造一個使用給定的錯誤資訊的基本 // `error` 值。 return -1, errors.New("can't work with 42") } // 返回錯誤值為 nil 代表沒有錯誤。 return arg + 3, nil}// 通過實現 `Error` 方法來自訂 `error` 類型是可以得。// 這裡使用自訂錯誤類型來表示上面的參數錯誤。type argError struct { arg int prob string}func (e *argError) Error() string { return fmt.Sprintf("%d - %s", e.arg, e.prob)}func f2(arg int) (int, error) { if arg == 42 { // 在這個例子中,我們使用 `&argError` 文法來建立一個 // 新的結構體,並提供了 `arg` 和 `prob` 這個兩個欄位 // 的值。 return -1, &argError{arg, "can't work with it"} } return arg + 3, nil}func main() { // 下面的兩個迴圈測試了各個返回錯誤的函數。注意在 `if` // 行內的錯誤檢查代碼,在 Go 中是一個普遍的用法。 for _, i := range []int{7, 42} { if r, e := f1(i); e != nil { fmt.Println("f1 failed:", e) } else { fmt.Println("f1 worked:", r) } } for _, i := range []int{7, 42} { if r, e := f2(i); e != nil { fmt.Println("f2 failed:", e) } else { fmt.Println("f2 worked:", r) } } // 你如果想在程式中使用一個自訂錯誤類型中的資料,你 // 需要通過類型斷言來得到這個錯誤類型的執行個體。 _, e := f2(42) if ae, ok := e.(*argError); ok { fmt.Println(ae.arg) fmt.Println(ae.prob) }}
運行程式
$ go run errors.gof1 worked: 10f1 failed: can't work with 42f2 worked: 10f2 failed: 42 - can't work with it42can't work with it