go defer机制和闭包结合
1. 学习不能只学皮毛,冰山一角,深入到下面去
eg:
defer的本质
2.1 defer不仅仅是栈的结构
2.2 defer 是如何存放入参和返回值的,如何执行的,这些都需要了解
defer 理解
输出:
29
10
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var age int = 10 defer fmt.Println(age) age = 29 defer fmt.Println(age)
defer + 闭包考察 f1()、f2()、f3() 函数分别返回什么?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
func f1() (r int) { defer func() { r++ }() return 0 } func f2() (r int) { t := 5 defer func() { t = t + 5 }() return t } func f3() (r int) { defer func(r int) { r = r + 5 }(r) return 1 }
as:
- f1() =1,return 把r设成0,然后defer把r改为1 ;
- f2() =5,return 把r设成5,然后defer改的是t,不影响返回值 ;
- f3() =5,return 把r设成1,然后defer把r改为r+5,但是用的r是defer设定时的r,=0;
- (靠,是1,r+5的r不是外面的r)
f(3)
defer内部的r非返回值r
eg:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
type Person struct { age int } func main() { person := &Person{28} // 1. defer fmt.Println(person.age) // 2. defer func(p *Person) { fmt.Println(p.age) }(person) // 3. defer func() { fmt.Println(person.age) }() person.age = 29 }
答案解析:
参考答案及解析:29 29 28。变量 person 是一个指针变量 。
1.person.age 此时是将 28 当做 defer 函数的参数,会把 28 缓存在栈中,等到最后执行该 defer 语句的时候取出,即输出 28;
2.defer 缓存的是结构体 Person{28} 的地址,最终 Person{28} 的 age 被重新赋值为 29,所以 defer 语句最后执行的时候,依靠缓存的地址取出的 age 便是 29,即输出 29;
3.很简单,闭包引用,输出 29;
又由于 defer 的执行顺序为先进后出,即 3 2 1,所以输出 29 29 28。
本文来自博客园,作者:易先讯,转载请注明原文链接:https://www.cnblogs.com/gongxianjin/p/17239958.html