go错误机制
Go 没有像 Java 和 .NET 那样的 try/catch 异常机制:不能执行抛异常操作。但是有一套 defer-panic-and-recover 机制。
go 的返回支持多个参数,一般由异常的信息的时候,将异常也返回给调用者,由调用者判断是否有异常需要处理。
生成异常并处理
errors 类中定义了多个生成错误的相关方法。
errors.new() 创建一个错误,用于向调用者返回error 信息
errors.Is() 判断是否是指定的错误类型
errors.As() As 方法的作用是在第一个参数 err 的调用链中寻找和第二个参数 target 类型相同的的错误,并把找到的第一个 err 的值赋给 target ,然后返回 true;如果没有找到则返回 false。
errors.Unwrap(err error) 解开内部的错误类型,一般可能会通过聚合了内部类型的自定义错误类型来返回
调用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| func devide(a int,b int) (float64,error) { if(b <= 0){ return 0,errors.New("被除数不允许小于等于0") } return float64(a) / float64(b),nil }
func TestErr(t *testing.T) { ret,err := devide(10,0) if(err != nil){ t.Error(err) return } t.Logf("得到的结果是 %f",ret) }
|
通过自定义错误类型来判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| var RangeError error = errors.New("数值范围错误,必须大于等于0")
var DevideZeroError error = errors.New("被除数不能等于0")
func devide(a int,b int) (float64,error) { if(a <0 || b < 0){ return 0,RangeError } if(b == 0){ return 0,DevideZeroError } return float64(a) / float64(b),nil }
func TestErr(t *testing.T) { ret,err := devide(-3,-1) if(err != nil){ if(errors.Is(err,DevideZeroError)){ fmt.Println("除数为0 了") } if(errors.Is(err,RangeError)){ fmt.Println("不能小于0了") } return } t.Logf("得到的结果是 %f",ret) }
|
panic
panic 用于处理一个不能恢复和处理的错误。
1 2 3 4 5 6 7
| func TestErr2(t *testing.T) { defer func() { t.Log("最终的结果执行。。。。") }() panic(errors.New("错误信息")) t.Log("结束===>") }
|
panic 不会影响 defer的执行
recover 恢复错误
recover 用于将程序从panic错误中恢复。
recover 只能用在 defer 修饰的函数中。
recover 是在当前的函数结束的时候对此函数能够处理的panic进行恢复,但是panic 开始位置到函数末尾的代码将不会执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| func errorFunc() { panic("有错误了") }
func method() { fmt.Println("method start ") defer func() { if err := recover();err != nil { fmt.Println("===>error") fmt.Printf("Panicing %s\r\n", err) } }() errorFunc() fmt.Println("method end ") }
func TestRecover(t *testing.T) { method() fmt.Println("test==end") }
|