![1127f3ca192e6dd1737d286d0b6881e4.png](https://img-blog.csdnimg.cn/img_convert/1127f3ca192e6dd1737d286d0b6881e4.png)
package main
import "fmt"
func main() {
/*
输出结果
1
5
1
*/
fmt.Println(f())
fmt.Println(f1())
fmt.Println(f2())
/*
输出结果
c: 1
b: 0
a: 0
*/
g()
}
/*
return xxx 不是一个原子指令
含有defer的函数执行过程为
1. 给返回值赋值
2. 执行defer函数
3. 返回到更上一级调用函数
*/
func f() (result int) {
defer func() {
result++
}()
return 0
}
func f1() (r int) {
t := 5
defer func() {
t = t + 5
}()
return t
}
func f2() (r int) {
defer func(r int) {
r = r + 5
}(r)
return 1
}
/*
defer函数的参数值是在申请defer时确定下来的
当defer函数声明时,对外外部的变量的引用方式有2种
1.作为函数的参数:在defer声明时就包值传递给defer,并将值缓存,调用defer的时候使用缓存的值进行计算
2. 最为闭包引用时,在defer函数执行时根据整个上下文确定当前的值
*/
func g() {
i := 0
defer fmt.Println("a:", i)
//闭包调用,将外部i传到闭包中进行计算,不会改变i的值,如上边的例3
defer func(i int) {
fmt.Println("b:", i)
}(i)
//闭包调用,捕获同作用域下的i进行计算
defer func() {
fmt.Println("c:", i)
}()
i++
}
/*
recover的返回值表示当前goroutine是否有panic行为
1、defer 表达式的函数如果定义在 panic 后面,该函数在 panic 后就无法被执行到
2、recover都是在当前的goroutine里进行捕获的,这就是说,对于创建goroutine的外层函数,
如果goroutine内部发生panic并且内部没有用recover,外层函数是无法用recover来捕获的,这样会造成程序崩溃
*/
func main() {
defer fmt.Println("111111")
defer func() {
if err := recover();err != nil{
fmt.Println(err)
}
}()
defer fmt.Println("22222")
panic("ffff")
defer fmt.Println("333")
}
参考资料
go defer,panic,recover详解 go 的异常处理www.jianshu.com![4f3c19b52dcf9e62d209aec058102716.png](https://img-blog.csdnimg.cn/img_convert/4f3c19b52dcf9e62d209aec058102716.png)