Go語言入門-錯誤處理
錯誤到底是什麼?
錯誤在go中是一個接口類型,便於自定義錯誤擴展。
// 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
}
創建第一個錯誤變量
標準庫創建錯誤變量的方式有兩種,
第一種是func New(text string) error;
第二種是func Errorf(format string, a …interface{}) error ;
func main() {
err := errors.New("my error")
err1 := fmt.Errorf("my error2")
fmt.Printf("%#v\n", err)
fmt.Printf("%#v\n", err1)
}
/**
output:
&errors.errorString{s:"my error"}
&errors.errorString{s:"my error2"}
*/
以上例子分別使用兩種方式創建錯誤。
標準庫錯誤的使用
var err = errors.New("my error")
var err1 = fmt.Errorf("my error")
func divide1(a, b int)(int, error) {
if b == 0 {
return 0, err
}
return a/b, nil
}
func divide2(a, b int)(int, error) {
if b == 0 {
return 0, err1
}
return a/b, nil
}
func main() {
result2, err2 := divide1(1, 0)
fmt.Println(result2, err2)
result3, err3 := divide2(1, 0)
fmt.Println(result3, err3)
fmt.Println(err2 == err3)
fmt.Printf("%p %#v\n", &err2, err2)
fmt.Printf("%p %#v\n", &err3, err3)
}
/**
ouput:
0 my error
0 my error
false
0xc00005a200 &errors.errorString{s:"my error"}
0xc00005a210 &errors.errorString{s:"my error"}
*/
以上例子可以看出errors提供的創建的錯誤是很簡單的一種錯誤,只保留了錯誤信息。需要注意的是使用errors創建錯誤不支持錯誤判等。說白了errors只是一種簡單的字符串error對象。
自定義錯誤
前面提到錯誤是接口,errors提供的錯誤創建是基於最簡單的字符來構建。下面我們可以手工構建一自己的錯誤類型。
/**
該例子來自《go語言學習筆記》
*/
/**
構建一個錯誤類型
*/
type DivError struct {
a, b int
}
/**
實現錯誤接口
*/
func (e DivError) Error() string {
errStr := fmt.Sprintf("Divison by Zero!")
return errStr
}
func div(a, b int) (int, error) {
if b == 0 {
return 0, DivError{a, b}
}
return a / b, nil
}
func main() {
//引發錯誤
d, err := div(10, 0)
if err != nil {
//錯誤匹配
switch e := err.(type) {
//優先匹配自定義錯誤
case DivError:
fmt.Println(e, e.a, e.b)
default:
fmt.Println(e)
}
log.Fatal(err)
}
fmt.Println(d)
}
/**
ouput:
0 Divison by Zero!
Divison by Zero! 10 0
2020/06/01 21:23:22 Divison by Zero!
*/
自定義錯誤通常以Error爲名稱後綴,同時當使用swtich進行類型匹配的時候,自定義的錯誤寫在前面,保證優先匹配到具體的錯誤類型。