Golang函数的Error类型应用技巧
更新时间:2023-07-13Golang函数的Error类型应用技巧
在编写 Golang 代码的过程中,我们经常需要在函数中返回错误信息。Go语言的 error 类型是一个接口类型,是内置包中的一个预定义接口,也是非常常见的一种类型。本文将介绍 Error 类型的应用技巧,帮助读者更好地利用该类型进行错误处理。
1. 使用errors.New()函数
errors.New()函数是非常简单且有用的构造函数,可以创建一个实现了 error 接口的简单类型。
package main import ( "errors" "fmt" ) func divide(num1 int, num2 int) (int, error) { if num2 == 0 { err := errors.New("cannot divide by zero") return 0, err } return num1 / num2, nil } func main() { res, err := divide(4, 2) if err != nil { fmt.Println(err) } else { fmt.Println(res) } }
上述代码演示了如何使用 errors.New() 函数创建一个包含错误信息的 error 对象。如果函数成功执行,则返回值为 nil,并输出结果,否则返回错误信息。
2. 自定义 Error 类型
对于一些重要的逻辑或应用程序,在使用 errors.New() 函数定义 error 类型时可能不够灵活,这时我们可以定义一个自定义的 Error 类型,以便可以更好地描述错误信息。
package main import ( "fmt" ) type DivisionError struct { dividend int divisor int } func (de DivisionError) Error() string { strFormat := `Cannot proceed, the divisor is zero. dividend: %d divisor: 0` return fmt.Sprintf(strFormat, de.dividend) } func divide(num1 int, num2 int) (int, error) { if num2 == 0 { dError := DivisionError{dividend: num1, divisor: num2} return 0, dError } return num1 / num2, nil } func main() { res, err := divide(4, 0) if err != nil { fmt.Println(err) } else { fmt.Println(res) } }
上述代码中,我们定义了一个叫做 DivisionError 的结构体,其包含被除数和除数两个参数。我们用 Error() 方法实现了 error 接口,由此定义了一个自定义的 Error 类型。在 divide 函数中,如果除数为 0,则返回这个自定义的 Error 类型。
3. 使用 panic 来处理错误
panic 是 Golang 中常用的错误处理方式之一,是一种高度定制化的方法,在某些情况下可能更加方便,但不应该经常使用,因为它会导致程序崩溃。
package main import "fmt" func divide(num1 int, num2 int) int { if num2 == 0 { panic("cannot divide by zero") } return num1 / num2 } func main() { defer func() { if err := recover(); err != nil { fmt.Println(err) } }() res := divide(4, 0) fmt.Println(res) }
上述代码中,我们使用 panic 抛出异常,在 main 函数中使用 recover 捕获异常并输出错误信息。
4. Wrap 和 Unwrap 方法
从 Golang 1.13 版本开始,内置的 errors.New() 和 fmt.Errorf() 函数提供了一个额外的附加参数,称为“wrap error”。这个 wrap error 提供了更完整的错误信息,包括该错误的根本原因。使用 wrap error 可以轻松地查看特定错误类型的堆栈跟踪。
package main import ( "errors" "fmt" "io/ioutil" ) func readFile() error { _, err := ioutil.ReadFile("test.txt") if err != nil { return fmt.Errorf("readFile: %w", err) } return nil } func main() { err := readFile() if err != nil { if wrappedErr := errors.Unwrap(err); wrappedErr != nil { fmt.Printf("original error: %T %v\n", wrappedErr, wrappedErr) } fmt.Printf("readFile error: %T %v", err, err) } }
上述代码中,我们首先读取一个不存在的文件,然后将错误信息写入日志,并返回错误信息。在 main 函数中,我们通过 errors.Unwrap() 来访问 wrapped error 来查看原始错误类型。如果发生了错误,我们将打印错误和错误类型。
总结
学习 Error 类型的应用技巧是 Golang 的基础知识之一,仅仅是代码处理过程中错误的简单描述,而它的使用却有很多细节内容。Error 类型不仅允许我们返回在函数调用中的错误,还包括创建自定义的错误类型,抛出处理 panic中断异常等特殊情况。我们要根据操作的具体场景,聚焦错误的根源,以便更好地辅导我们进行异常处理。.