go学习笔记(13)-基本语法-defer 与异常处理

defer 与异常处理

概述

Go没有try..catch 这种异常机制,而是使用panic和recover
panic在任何地方都可以执行,recover只有在defer调用的函数有效

defer

  • defer 用于定义在函数执行结束后执行的语句
  • 多个 defer 会形成 defer 栈,后定义的 defer 语句会被最先调用
  • 即使函数发生严重错误也会执行
  • 通过与匿名函数配合可以在return之后修改结果

定义多个 defer

func testDefer() {
	fmt.Println("a")
	defer fmt.Println("b")
	defer fmt.Println("c")
	defer func() {
		fmt.Println("d")
	}()
}
testDefer() //a d c b

改变返回值

由于 defer 在函数执行结束后执行,所以可以用于改变命名返回值的值

错误的用法

func changeResult(x int) int {
	defer func() {
		x++	//返回的值,改变变量没有用
	}()
	return x
}
x = changeResult(8)
fmt.Println("x", x) //x 8

正确的用法

func changeResult2(x int) (result int) {
	defer func() {
		result++
	}()
	return x
}
x = changeResult2(8)
fmt.Println("x", x) //x 9

panic与recover

panic用于向上传递异常,执行在 defer 之后,表示非常严重不可恢复的异常,会导致程序挂掉
recover可以对 panic 进行捕获,使panic 停止向上传递

使用 panic

func one() { fmt.Println("func one") }
func two() { fmt.Println("func two") }
func broken() {
	one()
	panic("func broken with Panic")
	two()
}
broken()

输出

func one
panic: func broken with Panic
异常消息...程序中断

使用 recover

func one() { fmt.Println("func one") }
func two() { fmt.Println("func two") }
func catch() {
	one()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("func catch with Recover")
		}
	}()
	panic("func broken with Panic")
	two()
}
catch()

输出

func one
func catch with Recover

注意

  • defer 需要放在 panic 之前定义
  • recover之后,逻辑并不会恢复到panic那个点去,函数还是会在defer之后返回
posted @ 2015-03-05 09:50  doitNow  阅读(236)  评论(0)    收藏  举报