GoLang:异常处理

学习自:Go教程137页

1、异常

程序运行时,发生了不被期望的事件,它阻止程序正常预期的运行

Go中两种处理异常的方式:

  • 程序异常时,将异常信息反馈给使用者
  • 程序异常时,终止运行立刻退出

2、打印异常信息

1)fmt包中的Errorf函数创建error类型,打印

var err error = fmt.Errorf("错误信息")
fmt.Println(err)

2)errors包中的New函数创建error类型,打印

var err error = errors.New("错误信息")
fmt.Println(err)

3、中断程序

Go中提供了一个panic函数,用于发生异常时终止程序的运行

func div(a,b int)(res int){
    if(b==0){
        panic("除数不能为0") //一旦传入的除数为0,程序就会终止
    }else{
        res=a/b
    }
    return
}

两种触发panic终止程序的方式:

  • 手动调用panic函数
  • 程序内部出现问题,自动触发panic函数

第二种情况很常见:数组越界、除0都会导致panic自动触发

var arr = [3]int{1,3,5}
arr[5]=666 //数组越界 自动触发panic

var res = 10/0//除数为0 自动触发panic

4、恢复程序(Java中的try...catch...)

Go中通过deferrecover来实现对panic异常的捕获,来让程序继续执行:

①在panic之前,定义一个延迟调用的匿名函数

func div(a,b int) (res int){
    //定义一个defer匿名函数,用于捕获panic异常
    //defer函数要在panic之前定义并调用(其实际执行时间在出错退出时)
    defer func(){
        if err:=recover;err!=nil{
                res=-1
                fmt.Println(err)
        }
    }()
    if(b==0){
        panic("除数不能为0")
    }else{    
            res=a/b
    }
    return
}

panic会沿着堆栈向外传播,因此也可以在外层捕获,但一定要保证defer在抛出panic之前调用

func div(a,b int) (res int){
    if(b==0){
        panic("除数不能为0")
    }else{    
            res=a/b
    }
    return
}

func main(){
    defer func(){
        if err:=recover();err!=nil{
            fmt.Println(err)
        }
    }()
    div(10,0) //发生panic的地方
}

②多个panic,只有第一个会被捕获

func test1(){
    defer func(){
        if err:=recover();err!=nil{
            fmt.Println(err)
        }
    }()
    panic("异常A")//一个panic就相当于return,其后的语句将不再执行
    panic("异常B")
}

③如果把异常写在了defer中,那么只有defer中的异常会被捕获

func test2(){
    defer func(){
        if err := recover();err!=nil{
            fmt.Println(err)//最后打印的是defer中的异常B
        }
    }()

    defer func(){
        panic("异常B")
    }()
    
    panic("异常A")
}

  

 

posted @ 2023-08-22 14:09  ShineLe  阅读(56)  评论(0编辑  收藏  举报