前言
类似于try...catch...finally
,go语言的错误处理机制是用defer
、panic
和recover
。
在Go语言中,错误和异常有error
和panic
两种。error
一般是程序开发者预知的,会进行适当的处理,比如检测用户输入不合法,抛出一个error
错误。panic
是程序开发者无法预知的异常,比如引用的对象值为空。
error
Go语言提供了两种创建error
的方法,它们底层是一样的,只是一种带格式,一种不带格式。
errors.New
fmt.Errorf
示例:
func ErrorUsage() {
err := errors.New("err: found 1")
if err != nil {
fmt.Println(err.Error())
}
err2 := fmt.Errorf("err: %s", "found 2")
if err2 != nil {
fmt.Println(err2.Error())
}
}
示例代码:计算倒数
package main
import (
"errors"
"fmt"
)
func reciprocal(n int) (float64,error) {
// 计算倒数
if n == 0 {
return 0,errors.New("0不能为倒数")
}
return float64(1) / float64(n), nil
}
func main() {
for i := 3;i >= 0;i-- {
ret,err := reciprocal(i)
// 对于函数返回值有错误error的情况下,要先判断一下函数有没有error。
// 如果有error,就把错误信息打印到控制台,否则输出计算得到的倒数值
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("1/%d = %.3f\n",i,ret)
}
}
}
-
error
作为函数的返回值,应放在返回值类型列表的末尾。
panic
在没有recover
的情况下,panic
常常会导致程序崩溃。
示例代码
package main
import (
"fmt"
)
func doPanic() {
// doPanic: 当捕获panic异常时触发
// 调用内置的recover()捕获panic异常
err := recover()
if err != nil {
// runtime error: integer divide by zero
fmt.Println("doPanic()捕获到异常:", err)
}
}
func main() {
// 注册捕获异常的处理函数
defer doPanic()
n := 0
ret := 1 / n
// 出现异常后,下面语句不会执行打印
fmt.Println("main ret = ",ret)
}
- 在
Go
语言中,recover
只在defer
调用的函数中有效,并且defer
要先注册,否则不能捕获到panic
异常。