1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > recover 没有捕获异常_Go的异常处理defer panic recover以及错误处理

recover 没有捕获异常_Go的异常处理defer panic recover以及错误处理

时间:2022-11-30 05:57:51

相关推荐

recover 没有捕获异常_Go的异常处理defer  panic  recover以及错误处理

一、异常处理

在异常处理方面,Go语言不像其他语言,使用try..catch.. finall..., 而使用defer, panic, recover,将异常和控制流程区分开。即通过panic抛出异常,然后在defer中,通过recover捕获这个异常,最后处理。

先来看一个案例吧,如下:funcmain(){

//立即执行函数

deferfunc(){//声明defer,

fmt.Println("----调用defer1start----")

iferr:=recover();err!=nil{

fmt.Println(err)//这里的err其实就是panic传入的内容

}

fmt.Println("----调用defer1end----")

}()

deferfunc(){//声明defer,

fmt.Println("----调用defer2start----")

iferr:=recover();err!=nil{

fmt.Println(err)//这里的err其实就是panic传入的内容

}

fmt.Println("----调用defe2rend----")

}()

panic("测试")

}

执行结果:

defer的思想类似于C++中的析构函数,就是在程序结束前执行的语句,defer后面可以是一个立即执行函数,也可以是一条语句。

defer可以多次,这样形成一个defer栈,后添加的会先被调用。

panic 是用来表示非常严重的不可恢复的错误的。在Go语言中这是一个内置函数,接收一个interface{}类型的值(也就是任何值了)作为参数。

panic的作用就像我们平常接触的异常,所以,调用panic会让程序不会继续往下执行(除非recover)。

recover捕获异常后的异常,不能再次被recover捕获。

二、错误处理

Go标准包提供的错误处理功能,error是个interface,如下:typeerrorinterface{

Error()string

}

且go提供了errorString结构体,其则实现了error接口,如下://errorStringisatrivialimplementationoferror.

typeerrorStringstruct{

sstring

}

func(e*errorString)Error()string{

returne.s

}

在errors包中,还提供了New函数,来实例化errorString,如下://Newreturnsanerrorthatformatsasthegiventext.

funcNew(textstring)error{

return&errorString{text}

}

于是,在定义函数的时候,我们就可以如下:funcadd(args...int)(int,error){

varsumint

iflen(args)==0{

return0,errors.New("参数为空")

}

for_,arg:=rangeargs{

sum+=arg

}

returnsum,nil

}

调用://立即执行函数

sum,err:=add()

iferr!=nil{

fmt.Println(err.Error())

}else{

fmt.Println(sum)

}

输出:

当然,我们也可以自己去实现error接口,如下:typemyErrorstruct{

curFilestring

codeint

descriptionstring

}

//实现Error方法,那么myError就实现了error接口

func(e*myError)Error()string{

returne.description

}

然后在函数中,使用我们自己定义的错误,如下:funcadd(args...int)(int,error){

varsumint

iflen(args)==0{

return0,&myError{curFile:"test.go",code:-1,description:"参数不能为空哦!"}

}

for_,arg:=rangeargs{

sum+=arg

}

returnsum,nil

}

三、案例

1、案例1

下面程序的输出:packagemain

import(

"fmt"

)

funcmain(){

doTest()

}

funcdoTest(){

deferfunc(){

panic("报错2")

}()

deferfunc(){

panic("报错1")

}()

panic("报错3")

}

解析:defer可以多次,这样形成一个defer栈,后添加的会先被调用,所以输出“报错1”应该在“报错2”之前,且defer有点类似析构函数,所以输出“报错3”在“报错1”之前。

上面程序输出如下:

2、案例2

下面程序的输出:packagemain

import(

"fmt"

)

funcmain(){

doTest()

fmt.Println("main捕获到错误:",recover())

}

funcdoTest(){

deferfunc(){

fmt.Println("1捕获到错误:",recover())

}()

fmt.Println("2捕获到错误:",recover())

panic("报错3")

}

分析:recover 只有在 defer 调用的函数中才有效,否则当panic时,recover无法捕获到panic,变回输出nil。

上面程序输出如下:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。