【Go】错误处理
· error类型是一个接口类型,也是一个Go语言的内建类型。在这个接口类型的声明中只包含了一个方法Error。这个方法不接受任何参数,但是会返回一个string类型的结果。它的作用是返回错误信息的字符串表示形象。我们使用error类型的方式通常是,在函数声明结果列表的最后,声明一个该类型的结果。同时在调用这个函数之后,先判断它返回的最后一个结果是否"不为nil"。如果不为nil那么就进入错误处理流程,否则就继续进行正常的流程。
package main import ( "errors" "fmt" ) func echo(request string) (response string, err error) { if request == "" { //如果request为空,调用error.New函数为结果赋值,然后忽略后边操作返回。response返回空字符串 err = errors.New("empty content") return } response = fmt.Sprintf("echo: %s", request) return //err值为nil } func main() { for _, req := range []string{"", "hello!"} { fmt.Printf("request: %s\n", req) resp, err := echo(req) if err != nil { fmt.Printf("error: %s\n", err) continue } fmt.Printf("response: %s\n", resp) } }
由于error是一个接口类型,所以即使同为error类型的错误值,它们的实际类型也可能不同。怎样判断一个错误值具体代表的是哪一类错误呢?
1)对于类型在已知范围内的一系列错误值,一般使用类型断言表达式或类型switch语句来判断
2)对于已有相应变量且类型相同的一系列错误值,一般直接使用判等操作来判断
3)对于没有响应变量且类型未知的一系列错误值,只能使用其错误信息的字符串表示形式来做判断
func underlyingError(err error) error { //获取和返回已知操作系统相关错误的潜在错误值 switch err := err.(type) { case *os.PathError: return err.Err //返回函数参数err的Err字段 case *os.LinkError: return err.Err case *os.SyscallError: return err.Err case *exec.Error: return err.Err } return err //直接把函数参数值返回 } printError := func(i int, err error) { if err == nil { fmt.Println("nil error") return } err = underlyingError(err) switch err { case os.ErrClosed: fmt.Printf("error(closed)[%d]: %s\n", i, err) case os.ErrInvalid: fmt.Printf("error(invalid)[%d]: %s\n", i, err) case os.ErrPermission: fmt.Printf("error(permission)[%d]: %s\n", i, err) } }
怎样根据实际情况给与恰当的错误值?
构建错误体系的基本方式有两种:
1)用类型建立起树形结构的错误体系,用统一字段建立起可追根溯源的链式错误关联。
2)预先创建一些代表已知错误的错误值
在这个国度中,必须不停地奔跑,才能使你保持在原地。如果想要寻求突破,就要以两倍现在速度奔跑!