golang日常开发系列之二--巧用defer
文章目录
更多精彩内容,请关注微信公众号:后端技术小屋
我们都知道,在golang中,有一种语言特性跟C++中的RAII特别相似,那就是defer。例如以下两段代码便可实现相同的效果
#include <iostream>
class Defer {
public:
Defer() { }
~Defer() {
std::cout << "defer" << std::endl;
}
};
int main() {
Defer d;
return 0
}
import "fmt"
func main() {
defer func() {
fmt.Println("defer")
}()
}
上述两段代码都会在main函数退出时,打印出字符串"defer”
但是golang中的defer和c++中的RAII还是有不同之处的。在c++中,RAII作用于对象的作用域,当离开对象作用域时,便触发RAII的执行,而一个函数中可能包含很多个不同的作用域。
int main() {
// 循环体内的作用域
for (size_t i=0; i<10; i++) {
Defer d; // 打印10次defer
}
// 花括号构成的作用域
{
Defer d; // 打印1次defer
}
return 0
}
而golang中没有作用域的概念,它不同于c++依赖程序员自行管理内存,golang是带GC的自动语言,对象的回收时机是程序员无法精确控制时机的。因此golang中defer只会在当前函数返回前才触发执行。那么有没有办法达到与c++中RAII类似的效果呢?答案是有的,通过创建匿名函数即可。
func printDefer() {
fmt.Println("defer")
}
func main() {
for i := 0; i < 10; i++ {
func() {
defer printDefer()
}()
}
func() {
defer printDefer()
}()
}
通过上述golang代码便可达到与c++ RAII类似的效果.
推荐阅读
更多精彩内容,请扫码关注微信公众号:后端技术小屋。如果觉得文章对你有帮助的话,请多多分享、转发、在看。
文章作者 后端侠
上次更新 2021-07-18