Go语言内置错误接口类型error。任何类型只要实现Error()string方法,都可以传递error接口类型变量。Go语言典型的错误处理方式是将erorr作为函数最后一个返回值。在调用函数时,通过检测其返回的eror值是否为nil来进行错误处理。
//$GOROOT/src/go/src/builtin/builtin.go
type error interface {
Error() string
}
Go语言标准库提供的两个函数返回实现了eror接口的具体类型实例,一般的错误可以使用这两个函数进行封装。遇到复杂的错误,用户也可以自定义错误类型,只要其实现eror接口即可。例如:
//http://golang.org/src/pkg/fmt/print.go
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
func Errorf(format string, a ...interface{}) error {
return errors.New(Sprintf(format, a...))
}
//http://golang.org/src/pkg/errors/errors.go
// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}
错误处理的最佳实践:
异常和错误在现代编程语言中是一对使用混乱的词语,下面将错误和异常做一个区分。
Go是一门类型安全的语言,其运行时不会出现这种编译器和运行时都无法捕获的错误,也就是说,不会出现untrapped error,所以从这个角度来说,Go语言不存在所谓的异常,出现的“异常”全是错误。
Go程序需要处理的这些错误可以分为两类:
对于运行时错误,程序员无法完全避免其发生,只能尽量减少其发生的概率,并在不影响程序主功能的分支流程上“recover”这些panic,避免其因为一个panic引发整个程序的崩溃。
go对于错误提供了两种处理机制:
所以对错误的处理也有两种方法,一种是通过返回一个错误类型值来处理错误,另一种是直接调用panic抛出错误,退出程序。
Go是静态强类型语言,程序的大部分错误是可以在编译器检测到的,但是有些错误行为需要在运行期才能检测出来。此种错误行为将导致程序异常退出。其表现出的行为就和直接调用panic一样:打印出函数调用栈信息,并且终止程序执行。
在实际的编程中,error和panic的使用应该遵循如下三条原则:
进一步浓缩为两条规则:
程序发生的错误导致程序不能容错继续执行,此时程序应该主动调用panic或由运行时抛出panic。
程序虽然发生错误,但是程序能够容错继续执行,此时应该使用错误返回值的方式处理错误,或者在可能发生运行时错误的非关键分支上使用recover捕获panic。
G0程序的有些错误是在运行时进行检测的,运行期的错误检测包括空指针、数组越界等。如果运行时发生错误,则程序出于安全设计会自动产生panic。另外,程序在编码阶段通过主动调用panic来进行快速报错,这也是一种有效的调试手段。