Go语言中的异常处理

256 阅读2分钟

我正在参加「掘金·启航计划」

go中不像其它语言有try catch语法,go中可以使用panic抛出错误,recover捕获错误,然后正产处理。

1、panic

func panic(v interface{})
  • 内建函数
  • 假如函数中书写了panic语句,会终止其后要执行的代码,在panic所在函数内如果要存在要执行的defer函数列表,按照defer的逆序执行。
  • 返回函数F的调用者G,在G中,调用函数F语句之后的代码不会执行,假如函数G中存在要执行的defer函数列表,按照defer的逆序执行,这里的defer有点类似try-cache-finally中的finally
  • 直到goroutine整个退出,并报告错误

2、recover

func recover() interface{}
  • 内建函数
  • 用来控制一个goroutine的panicking行为,捕获panic,从而影响应用的行为。
  • 一般的调用建议:
    • 在defer函数中,通过recver来终止一个goroutine的panicking过程,从而恢复正常代码的执行
    • 可以捕获通过panic传递的error

简单来讲,go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理。需要注意以下几点:

  • 利用recover处理panic异常,defer必须放在panic之前定义,recover只有在defer调用的函数中才有效,否则当panic时,recover无法捕获到panic。
  • recover处理异常之后,逻辑并不会恢复到panic那个点去,函数跑到defer之后的那个点
  • 多个defer会形成defer栈,后进先出,后定义的defer语句会被最先调用。

示例:

func main()  {
	defer func(){
		if err := recover(); err != nil {
			fmt.Printf("err:%s\n", err) 
		}
	}()
    
	var chan1 = make(chan int, 5)
	close(chan1)
	chan1<-1 //向已经关闭的通道发送数据会引发panic
}