Go的错误和异常
Go的错误处理
Go的错误处理:Go没有像java,c#语言中的try...catch异常处理方式,而是通过函数返回值逐层向上抛,这种设计,鼓励工程师在代码中显示的检查错误,而非忽略错误,好处就是避免漏掉本应该处理的错误,但是带来一个弊端,让代码变得冗余
错误和异常
错误指的是可能出现问题的地方出现了问题,比如打开一个文件失败,这种情况在人们的意料之中异常指的是不应该出现问题的地方出现了问题,比如引用了空指针,这种情况在人们的意料之外,可见,错误是业务过程中的一部分,而异常不是Go中的错误也是一种类型,错误用内置的error类型表示,按照惯例,如果一个函数或者方法返回一个错误,那么它必然是函数返回的最后一个值
panic和recover
当程序运行时,如果遇到引用空指针,下标越界,或者显示调用panic函数等情况,则先出发panic函数的执行,然后调用defer 语句,调用者继续传递panic,因此该过程一直在调用栈中重复发生:函数停止执行,调用延迟执行函数等等,如果一路在延迟函数中没有recovery函数的调用,则会到达该协程的起点,该协程结束,然后终止其他协程,包括主协程
panic:
-
内建函数
-
加入函数F中使用了panic语句,会终止其后需要执行的代码,在Panic所在函数中如果存在要执行的defer函数列表,按照defer的逆序执行,返回函数的调用者G,调用函数F语句之后的代码不会执行,假如G中存在要执行的defer函数列表,按照defer的逆序执行,直到goroutine整个退出,并报告错误
recover:
-
内建函数
-
用来控制一个goroutine的Panicing行为,捕获Panic,从而影响应用的行为3.一般的调用建议 在defer函数中。通过reover来终止一个panic 2.可以获取通过panic传递的error
简单的来说,go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常。进行正常处理
场景区分
什么时候用错误表达,什么时候用异常表达,就必须要有一套规则,否则很容易出现一切都是错误或者一切都是异常的情况
异常处理的作用场景:
-
空指针引用
-
下标越界
-
除数为0
-
不应该出现的分支,比如default
-
输入不应该引起函数错误
其他场景我们使用错误处理,这使得我们的函数接口很精炼,对于异常,我们可以选择在一个合适的上游去recover,并打印堆栈信息,使得部署之后的程序不会终止