var file *os.File var err error file, err = os.Open("something.txt") if err != nil { // 处理打开文件时的错误,比如panic panic(file) } // 处理文件 fmt.Println(file.Stat()) // 处理关闭文件时的错误,比如直接忽略 _ = file.Close()
Go在标准库里提供了一种错误表现形式:error接口,定义很简单:
1 2 3 4 5 6 7
package builtin
// The error built-in interface type is the conventional interface for // representing an error condition, with the nil value representing no error. typeerrorinterface { Error() string }
var err1 error = Error1("hello") // Error1可以被视为Error var err2 error = &Error2{msg: "world"} // Error2也可以被视为Error
如何创建error
Go原生提供了两种方式来创建一个error
1 2
var err1 error = errors.New("error msg") var err2 error = fmt.Errorf("error msg: %s", "hello")
前者比较简单,单纯地创建了一个string的封装类型:
1 2 3 4 5 6 7 8 9 10
package errors
// New returns an error that formats as the given text. // Each call to New returns a distinct error value even if the text is identical. funcNew(text string)error { return &errorString{text} }
// errorString is a trivial implementation of error. type errorString struct{ s string }
// Errorf formats according to a format specifier and returns the string // as a value that satisfies error. funcErrorf(format string, a ...interface{})error { return errors.New(Sprintf(format, a...)) }
myRead := func() ([]byte, error) { ... if ... { returnnil, fmt.Errorf("myRead: %w", io.EOF) } ... } buf, err := myRead() if errors.Is(err, io.EOF) { // do something }
又比如,用errors.As替代.(type)来做类型断言:
1 2 3 4 5 6 7 8 9
err := dial80() if err != nil { var opErr *net.OpError // 判断err是否为超时错误 if ok := errors.As(err, &opErr); ok && opErr.Timeout() { // do something } // do something }