The error handling in the Go language is different from other languages. It treats errors as a value, and emphasizes more on judging errors and handling errors, rather than a general catch to catch exceptions.
Table of contents
Error interface
The Go language treats errors as a special value, and does not support try/catch
the way of catching exceptions in other languages.
Error interface
The Go language uses a named error
interface to represent error types.
type error interface {
Error() string
}
error
The interface contains only one method - Error
, which needs to return a string describing the error message.
When a function or method needs to return an error, we usually use the error as the last return value. For example, the function of opening a file in the standard library os below.
func Open(name string) (*File, error) {
return OpenFile(name, O_RDONLY, 0)
}
Since error is an interface type, the default value is zero nil
. So we usually compare the error returned by the calling function with nil
, to determine whether the function returns an error. For example, you will often see error judgment codes like the following.
file, err := os.Open("./xx.go")
if err != nil {
fmt.Println("打开文件失败,err:", err)
return
}
Notice
When we use fmt
the package to print an error, the Error method of the error type will be called automatically , that is, the description information of the error will be printed out.
create error
We can customize error according to our needs, the easiest way is to create an error using the function errors
provided by the package .New
errors.New
The function signature is as follows,
func New(text string) error
It takes a string argument and returns an error containing that string. We can quickly create an error when a function returns.
func queryById(id int64) (*Info, error) {
if id <= 0 {
return nil, errors.New("无效的id")
}
// ...
}
Or used to define an error variable, for example, the standard library io.EOF
error is defined as follows.
var EOF = errors.New("EOF")
fmt.Errorf
When we need to pass in formatted error description information, using fmt.Errorf
is a better choice.
fmt.Errorf("查询数据库失败,err:%v", err)
However, the above method will lose the original error type, and only get the text information of the error description.
In order not to lose the error chain of the function call, fmt.Errorf
a special formatting verb %w
can be used when using it, and a new error can be obtained by repackaging based on an existing error.
fmt.Errorf("查询数据库失败,err:%w", err)
For this secondary packaging error, errors
the package provides the following three methods.
func Unwrap(err error) error // 获得err包含下一层错误
func Is(err, target error) bool // 判断err是否包含target
func As(err error, target interface{}) bool // 判断err是否为target类型
wrong structure type
In addition, we can also define the structure type and implement the ` error
interface.
// OpError 自定义结构体类型
type OpError struct {
Op string
}
// Error OpError 类型实现error接口
func (e *OpError) Error() string {
return fmt.Sprintf("无权执行%s操作", e.Op)
}