Error接口看起来非常简洁:

type Error interface{
    Error() string
}

这个接口很容易满足,不幸的是,这也很容易导致需要根据收到的错误与采取操作的包的混淆。

在Go中有很多方法可以创建错误,本节将探讨基本错误的创建,已分配值或类型的错误,以及使用结构的自定义错误。

实践

创建basicerrors.go:

package basicerrors

import (
    "errors"
    "fmt"
)

// ErrorValue创建了包级错误
// 可以采用这样的方式判断: if err == ErrorValue
var ErrorValue = errors.New("this is a typed error")

// TypedError创建了包含错误类型的匿名字段
// 可以采用断言的方式判断:err.(type) == ErrorValue
type TypedError struct {
    error
}

//BasicErrors 演示了错误的创建
func BasicErrors() {
    err := errors.New("this is a quick and easy way to create an error")
    fmt.Println("errors.New: ", err)

    err = fmt.Errorf("an error occurred: %s", "something")
    fmt.Println("fmt.Errorf: ", err)

    err = ErrorValue
    fmt.Println("value error: ", err)

    err = TypedError{errors.New("typed error")}
    fmt.Println("typed error: ", err)

}

创建custom.go:

package basicerrors

import (
    "fmt"
)

// CustomError 实现了Error接口
type CustomError struct {
    Result string
}

func (c CustomError) Error() string {
    return fmt.Sprintf("there was an error; %s was the result", c.Result)
}

// SomeFunc 返回一个 error
func SomeFunc() error {
    c := CustomError{Result: "this"}
    return c
}

创建 main.go:

package main

import (
    "fmt"

    "github.com/agtorre/go-cookbook/chapter4/basicerrors"
)

func main() {
    basicerrors.BasicErrors()

    err := basicerrors.SomeFunc()
    fmt.Println("custom error: ", err)
}

这会输出:

errors.New: this is a quick and easy way to create an error
fmt.Errorf: an error occurred: something
typed error: this is a typed error
custom error: there was an error; this was the result

说明

无论你是使用errors.New,fmt.Errorf还是自定义错误,最重要的是你应该永远不要在代码中忽略错误。这些不同的错误定义方法提供了很大的灵活性。例如,你可以在结构中添加额外的函数,以进一步查看可能发生的错误并将接口转换为调用函数中的错误类型,以获得一些额外的功能。

错误接口本身非常简单,唯一的要求是返回一个有效的字符串。将它连接到一个结构可能对某些高级应用程序很有用,这些应用程序在整个过程中都有统一的错误处理,同时也希望能够与其他应用程序进行良好地协作。

最后编辑: kuteng  文档更新时间: 2021-01-03 15:03   作者:kuteng