Skip to content

Latest commit

 

History

History
92 lines (77 loc) · 1.89 KB

index.md

File metadata and controls

92 lines (77 loc) · 1.89 KB

defer 语句

defer 是G o语言提供的一种用于注册延迟调用的机制:让函数或语句可以在当前函数执行完毕后(包括通过 return 正常结束或者 panic 导致的异常结束)执行,它会经常被用于关闭文件描述符、关闭数据库连接以及解锁资源等。

func main() {
	fmt.Println("start")
	for i := 0; i < 5; i++ {
		defer fmt.Println(i)
	}
	fmt.Println("end")
	
	/*
	输出结果:
	start
    end
    4
    3
    2
    1
    0
}

defer 后面跟的内容除了可以是一行语句以外,也可以是一个函数/匿名函数。

func closeAll() {
	fmt.Println("close all 1 !")
}
func main() {
	fmt.Println("start")
	defer closeAll()
	defer func() { fmt.Println("close all 2") }()
	fmt.Println("end")
}

输出结果

panic

当一个函数在执行过程中出现了异常或遇到 panic(),正常语句就会立即终止,然后执行 defer 语句,再报告异 常信息,最后退出 goroutine。如果在 defer 中使用了 recover() 函数,则会捕获错误信息,使该错误信息终止报告。

func main() {
	fmt.Println("start")
	defer func() { fmt.Println("close all") }()
	panic("ERROR")
	fmt.Println("end")
}

输出结果为

start
close all
panic: ERROR

goroutine 1 [running]:
main.main()
        /Users/zhangyanfei/work_go/go-training/2-code-organize/defer/main.go:12 +0xb7

Process finished with exit code 2

注意:panic 只会触发当前 Goroutine 的延迟函数调用;

recover

recover 只有在 defer 函数中调用才会生效

fmt.Println("start")
defer func() {
    if r := recover(); r != nil {
        fmt.Println("Recovered in f", r)
    }
}()
panic("ERROR")
fmt.Println("end")

panic之后虽然end同样没有输出,但是和没有recover的demo相比,程序并没有异常退出。

start
Recovered in f ERROR

Process finished with exit code 0