GoLang:异常处理

学习自:Go教程137页

1、异常

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

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

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

2、打印异常信息

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

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

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

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

3、中断程序

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

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

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

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

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

1
2
3
4
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之前,定义一个延迟调用的匿名函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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之前调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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,只有第一个会被捕获

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
func test2(){
    defer func(){
        if err := recover();err!=nil{
            fmt.Println(err)//最后打印的是defer中的异常B
        }
    }()
 
    defer func(){
        panic("异常B")
    }()
     
    panic("异常A")
}

  

 

posted @   ShineLe  阅读(97)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示