Go 语言中 defer 的变量快照在什么情况下会失效?
Go 语言中 defer 的变量快照在什么情况下会失效?
重点回答
在 Go 语言中,defer 的变量快照是指在 defer 语句定义时所捕获的变量的状态。但有些情况下,defer 语句中的变量快照可能会失效,导致不如预期那样行为,如下:
1)匿名函数闭包:当 defer 语句中使用的匿名函数捕获了外部变量时。如果变量的值在 defer 语句定义后发生变化,defer 执行时会使用变化后的值。
2)引用类型:当 defer 引用持有引用类型的变量(如指针、切片、映射、通道和函数)时,虽然引用本身的地址不会变,但指向的内容可能变化,这也会导致最终的结果和预期的快照结果不同。
扩展知识
在编程的时候,经常需要打开一些资源,比如数据库连接、文件、锁等,这些资源需要在用完之后释放掉,否则会造成内存泄漏。在 Go 中 defer 一般用于资源清理、文件关闭、解锁互斥量等操作。
1) defer常见用法
在函数开始时定义 defer ,确保退出时资源能够正确释放。
1 | package main |
2)闭包的defer变量
1 | package main |
输出结果:
1 | Normal x: 1 |
3)defer+引用类型
当 defer 引用持有引用类型的变量时,如果变量指向的内容发生变化,这也会导致最终的结果和预期的快照结果不同。
1 | package main |
输出结果:
1 | Normal x: [1] |
4)defer+函数参数
把变量作为函数的参数传递给匿名函数,defer 后面跟的就是一个函数调用了。
1 | package main |
输出结果:
1 | 2 |
Comments