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中通过defer和recover来实现对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" ) } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性