Go里的流程控制如下:
- if - else条件语句
- swich - case选择语句
- for - range 循环语句
- goto无条件跳转语句
- defer延迟执行
1.延迟调用
defer的用法很简单,只要在后面跟一个函数的调用,就能实现将这个xxx函数的调用延迟到当前函数执行完后再执行
defer xxx()
这是一个很简单的例子,可以快速理解defer的使用效果
import "fmt" func myfunc() { fmt.Println("B") } func main() { defer myfunc() fmt.Println("A") }
输出如下
A B
也可以简写成如下,输出结果是一致的
import "fmt" func main() { defer fmt.Println("B") fmt.Println("A") }
2.即时求值的变量快照
使用defer只是延迟调用函数,此时传递给函数里的变量,不应该收到后续程序的影响
import "fmt" func main() { name := "go" defer fmt.Println(name) // 输出: go name = "python" fmt.Println(name) // 输出: python }
输出如下,可见给 name 重新赋值为 python
,后续调用 defer 的时候,仍然使用未重新赋值的变量值,就好像在 defer 这里,给所有的变量做了一个快照一样
python go
3.为什么要有defer
若是没有 defer,你可能这样写代码
func f() { r := getResource() //0,获取资源 ...... if ... { r.release() //1,释放资源 return } ...... if ... { r.release() //2,释放资源 return } ...... if ... { r.release() //3,释放资源 return } ...... r.release() //4,释放资源 return }
使用了 defer 后,代码就显得简单直接了,不管你在何处 return,都会执行 defer 后的函数
func f() { r := getResource() //0,获取资源 defer r.release() //1,释放资源 ...... if ... { ... return } ...... if ... { ... return } ...... if ... { ... return } ...... return }
defer xxx()