Go 错误处理
一:error接口
Go语言引入了一个关于错误处理的标准模式,即error接口,该接口的定义如下:
type error interface {
Error() string
}
使用例子如下
func Add(a,b int) error{
if a>0 {
err:=error.New("我的错误信息")
return err
}
return nil
}
实现自定义的error类型
type PathError struct{ //1:定义一个struct == C# class
Err error //2:定义一个error类型的成员
Path string
}
如何实现将PathError的类型是error类型呢?这里有一个接口的概念 ,后续的会介绍到
func (this *PathError) Error() string{ //3:这边的Error等价与 C#中的 class ->method 感觉要是能够给Error写在struct中就更好了
return "我的错误信息" //4:因为这边的PathError 有个一名称为 Error()的方法 代表了这个自定义类型实现了error 接口,后面我们就可以认为
//PathError类型实现了error接口了,我们就可以将Path传递到error类型
}
func myExampleError(aa string) error{
return &PathError{"stat", nil}
}
二: defer关键字
提到这个关键字,我们可以想一下C#中连接数据库的时候使用
SqlConnect conn=new SqlConnect();
conn.open()
/*代码段*/
conn.close()
其中conn在开启后必须等待做完很多操作后才能够将conn关闭 ,这个操作经常会忘记,或者中间错误也会造成conn无法关闭的问题
后面为了解决这个问题提出有using(SqlConnect conn=new SqlConnect())来实现自动释放conn接口
GO语言中的defer就等价与它
使用方法
file.open()
defer file.close() 这边就是开启一个资源后,直接将该资源释放 ,而释放的过程实际上是在当前这个函数关闭后才执行的,所以我们开放
一个资源后要紧记,立马使用defer释放,这样就可以避免资源无法释放的问题了
注意:一个函数中可以存在多个defer语句,因此需要注意的是,defer语句的调用是遵照先进后出的原则,即最后一个defer语句将最先被执行
三:panic()和recover()
func panic(interface{})
func recover() interface{}
当在一个函数执行过程中调用panic()函数时,正常的函数执行流程将立即终止,但函数中之前使用defer关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致逐层向上执行panic流程,直至所属的goroutine中所有正在执行的函数被终止。错误信息将被报告,包括在调用panic()函数时传入的参数,这个过程称为错误处理流程。
recover()函数用于终止错误处理流程。一般情况下,recover()应该在一个使用defer关键字的函数中执行以有效截取错误处理流程。如果没有在发生异常的goroutine中明确调用恢复过程(使用recover关键字),会导致该goroutine所属的进程打印异常信息后直接退出。以下为一个常见的场景。
我们对于foo()函数的执行要么心里没底感觉可能会触发错误处理,或者自己在其中明确加入了按特定条件触发错误处理的语句,那么可以用如下方式在调用代码中截取recover():
defer func() {
if r := recover(); r != nil {
log.Printf("Runtime error caught: %v", r)
}
}()
foo()
上面的两个函数我理解的不是特别深,等待后续的继续学习。