golang defer讲解
来源:互联网 发布:mac 查看安装的程序 编辑:程序博客网 时间:2024/06/06 02:09
1.defer 是在函数退出前调用,多个defer遵循 先进后出 的原则调用;常用来做资源清理,关闭文件,解锁等操作
func deferTest() {defer func() {fmt.Println("func1...")}()func() {fmt.Println("func2...")}()defer func() {fmt.Println("func3...")}()}
2.defer调用所需参数在defer语句被压入栈中时获得(拷贝值),尽管defer语句是在函数返回前真正执行
func main() {x := 5defer fmt.Println("println=", x)defer func(y int) {fmt.Println("func=", y)}(x)x += 10fmt.Println(x)}输出结果:
15
func= 5
println= 5
3.defer函数能够读取外围函数的返回值并进行更改操作
func main() {v := c()fmt.Println(v)}func c() (i int) {defer func() { i++ }()return 1}输出结果:
2
以上代码c()函数可以解析为:
1.将defer函数压入栈中
2.给返回值i赋值为1,即i=1
3.执行defer函数,修改返回值i
4.执行空的return,即return;
4.看以下demo:
func main() {v := c()fmt.Println(v)}func c() (i int) {x := 1defer func(x int) { x++ }(x)return x}输出结果:
1
上面函数c()这段代码可以解析为:
1.给变量x赋值为1
2.将defer函数压入栈中,同时拷贝变量x的值给defer函数中的x(注意:这是两个不同的x)
3.给返回值i赋值为x,即i = 1
4.执行defer函数,defer函数中的x为2(外围函数中的x值仍然为1)
5.执行return;
总结:
1.当执行到defer语句时,会先把它压入栈中,此时以值传递的方式获取defer语句所需要的参数,等它的外围函数返回前,开始按 先进后出 的原则执行defer语句
2.return xxx;语句并不是一个原子操作,当有defer语句时,return xxx可以解释为: 先给返回值赋值,然后执行defer语句,最后执行空的return。所以defer语句有可能更改返回值。
阅读全文