golang用panic和recover作业务流程中断的尝试

随着使用golang愈来愈频繁,发现golang有一个地方很是不方便,就是在错误处理方面。先来看看golang中一般的错误处理方法:golang

一般的error处理

package main
 
import (
    "errors"
    "fmt"
)
 
func a() (err error) {
    err = errors.New("错误")
    return
}
 
func main() {
    err := a()
    if err != nil {
        fmt.Println(err)
    }
}

函数在返回的时候增长error类型的返回值,若是有错误则赋值给err,在调用函数处对err进行判断,若是不为nil则处理错误。这种方式在嵌套的层少的时候还好办,要是嵌套的层多了那就要一级一级的返回err,显然会很麻烦。以下面的代码: api

package main
 
import (
    "errors"
    "fmt"
)
 
func a() (err error) {
    err = b()
    if err != nil {
        return
    }
    err = c()
    if err != nil {
        return
    }
    err = errors.New("a内错误")
    return
}
 
func b() (err error) {
    err = errors.New("b内错误")
    return
}
 
func c() (err error) {
    err = errors.New("c内错误")
    return
}
 
func main() {
    err := a()
    if err != nil {
        fmt.Println(err)
    }
}

a函数内调用了b和c函数,调用后都要进行err != nil的判断,若是再来个d方法,e方法,那岂不是很是麻烦。在实际开发的时候,这种多层嵌套也常常存在,好比用户注册功能就要判断不少东西:表单验证是否OK;用户是否已经存在;数据插入是否OK等等。函数

用panic的尝试

因而我就想有没什么办法更加方便,至少不用调用每一个函数都判断下err!=nil,这样就能够省掉三行代码。了解到golang中的panic方法能够直接中断流程,感受到沿着这个应该能找到解决方法。了解了下panic的详细使用,其实也很简单,就是panic一下,若是须要捕获这个panic的错误,就在外围的方法事先声明recover方法。看下代码:spa

 

package main
 
import (
    "log"
)
 
func main() {
    defer func() {
        if r := recover(); r != nil {
            log.Printf("Runtime error caught: %v", r)
        }
    }()
 
    a()
}
 
func a() {
    panic("a内错误")
}

a函数内抛出了错误,被外围事先defer的函数recover到,接着就能对错误进行处理了。用这样的方式来改造上面用err处理的代码看看。 code

package main
 
import (
    "log"
)
 
func a() {
    b()
    c()
 
    panic("a内错误")
    return
}
 
func b() {
    panic("b内错误")
}
 
func c() (err error) {
    panic("c内错误")
}
 
func main() {
    defer func() {
        if r := recover(); r != nil {
            log.Printf("Runtime error caught: %v", r)
        }
    }()
 
    a()
}

能够看到整个代码都简洁了不少,固然这里的代码比较简单可能看不出什么太大效果,在业务较为繁杂、常常要作各类校验的时候就能够显现出简洁了。接口

在开发api接口项目的时候,我会封装好recover的方法用来处理内部返回的错误信息,而后统一输出到客户端,感受便捷不少。开发

相关文章
相关标签/搜索