go语言中的defer
- 当执行defer时,会将defer后面的语句压入到单独的栈(defer栈)。
- 当函数执行完毕后(遇到return,panic或者函数顺序执行完),在从defer栈中,按照先入后出的方式,执行。
- 如果函数的定义为匿名返回值,则defer无法修改。
- 如果函数的定义为具名返回值,则defer会进行修改。
- 在函数中,需要创建资源,文件句柄,数据库连接等,在执行完毕后,关闭这些资源。go提供了defer(延时机制)。
顺序执行遇到defer情况
1 | package main |
打印先输出fmt.Println里面的内容,接着输出最后一个defer内容,最后输出第一个defer的内容。
1 | 结果为 3 |
defer遇到return的情况
- 当defer遇到return,在return之前,会执行defer的内容,然后再进行return。
1 | package main |
虽然有return, 但defer在栈里面,在return之前会先进行执行defer内容
输出内容为:
1 | 结果为 3 |
- 但如果defer在return后面, 则不会执行defer内容,遇到return就返回了。
1 | package main |
输出内容只有”我是if”,因为在if里面直接return了,不会触发defer。
defer遇到匿名返回值情况
1 | package main |
输出为:
1 | ccc |
因为没有指定返回值,只指定了返回类型(string),所以defer内容无法修改result内容,打印出来的result为”ccc”。
defer遇到具名返回值情况
1 | package main |
输出为:
1 | Change World |
因为指定了返回值result, 所以defer的内容可以影响result,结果为Change World.
refer:
https://blog.golang.org/defer-panic-and-recover
https://golang.org/ref/spec#Defer_statements
https://stackoverflow.com/questions/37248898/how-does-defer-and-named-return-value-work