函数返回值处理异常
golang为了避免像写Java一样滥用try catch,可以使用函数多返回值的特性来进行异常处理,例如:
type error interface{
//定义一个错误类型
Error() string
}
func sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("负数平方根不能是0")
}
return math.Sqrt(f), nil
}
func main() {
Println(sqrt(22.65))
Println(sqrt(-100))
}
输出:
4.759201613716317 <nil>
0 负数平方根不能是0
所以如果返回的error类型部位nil的时候,就说明发生了异常
defer、panic、recover处理异常
panic
是golang一个内建函数,可以中断原有的控制流程,进入一个令人恐慌的流程中。当函数F调用panic,函数F的执行被中断,但是F中的延迟函数会正常执行,然后F返回到调用它的地方。在调用的地方,F的行为就像调用了panic。这一过程继续向上,直到发生panic的goroutine中所有调用的函数返回,此时程序退出。恐慌可以直接调用panic产生。也可以由运行时错误产生,例如访问越界的数组。
Recover
是一个内建的函数,可以让进入令人恐慌的流程中的goroutine恢复过来。recover仅在延迟函数中有效。在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。如果当前的goroutine陷入恐慌,调用recover可以捕获到panic的输入值,并且恢复正常的执行
在实际使用的时候,我们可以使用defer函数,在异常结束程序前拿到recover返回的错误值,进行处理
示例:
func f() {
Println("a")
panic(55) // 错误,类似java throw,过程会向上传递直到defer执行
Println("b")
Println("f")
}
func main() {
defer func() {
Println("c")
if err := recover(); err != nil {
Println(err)
}
Println("d")
}()
f()
}
这样,我们在defer执行的时候可以拿到error的值,就像是java里面catch了一个exception一样
输出结果:
a
c
55
d