实现了error接口的错误类型,可以直接return并处理
通过panic方法触发,或者因为空指针等运行时异常导致的错误
一般错误都是通过return接收并处理了,如果程序发生了可以预知的不可恢复的错误,就可以使用panic方法抛出。panic生成一个允许时的错误,并终止程序继续执行。panic接收一个任意类型的参数,通常情况下是string类型。
golangfunc main() {
// some code
panic(http.ListenAndServe(":8080", nil))
}
当panic被调用或者运行时错误发生的时候,程序会立即停止当前方法的执行,取出当前协程的执行堆栈,执行延迟方法,直到到达顶层堆栈,然后终止程序。如果想要程序继续执行,可以使用recover方法重新获得协程的控制权,继续执行程序。 recover方法会停止堆栈的取出,并且返回panic方法的参数。因为错误发生的时候,只有延迟方法会被执行,所以recover通常仅在延迟方法中生效。
golangfunc server(workChan <-chan *Work) {
for work := range workChan {
go safelyDo(work)
}
}
func safelyDo(work *Work) {
defer func() {
if err := recover(); err != nil {
log.Println("work failed:", err)
}
}()
do(work)
}
由于panic只会终止当前协程,不会破坏整个程序。在上例中,通过safelyDo方法,在某个协程出错的时候,错误会被捕获并打印下来。 下面看一个更复杂的例子,正则表达式库使用panic处理表达式解析错误。
golang// Error is the type of a parse error; it satisfies the error interface.
type Error string
func (e Error) Error() string {
return string(e)
}
// error is a method of *Regexp that reports parsing errors by
// panicking with an Error.
func (regexp *Regexp) error(err string) {
panic(Error(err))
}
// Compile returns a parsed representation of the regular expression.
func Compile(str string) (regexp *Regexp, err error) {
regexp = new(Regexp)
// doParse will panic if there is a parse error.
defer func() {
if e := recover(); e != nil {
regexp = nil // Clear return value.
err = e.(Error) // Will re-panic if not a parse error.
}
}()
return regexp.doParse(str), nil
}
当doParse正常运行的时候会返回nil,否则返回Error,如果返回的错误不是Error类型,会重新panic
本文作者:谭三皮
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!