golang日常开发系列之二--巧用defer

简介: 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类似的效果.

相关文章
|
4月前
|
缓存 弹性计算 API
用 Go 快速开发一个 RESTful API 服务
用 Go 快速开发一个 RESTful API 服务
|
29天前
|
Go 数据安全/隐私保护 开发者
Go语言开发
【10月更文挑战第26天】Go语言开发
37 3
|
1月前
|
Java 程序员 Go
Go语言的开发
【10月更文挑战第25天】Go语言的开发
29 3
|
2月前
|
Go Python
通过 atexit 模块让 Python 实现 Golang 的 defer 功能
通过 atexit 模块让 Python 实现 Golang 的 defer 功能
21 2
|
3月前
|
Go API
Golang语言开发注意事项
这篇文章总结了Go语言开发中的注意事项,包括语法细节、注释使用、代码风格、API文档的利用以及如何使用godoc工具来生成文档。
42 2
|
4月前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
111 0
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
4月前
|
监控 测试技术 API
|
4月前
|
JSON 编解码 中间件
go-zero代码生成器助你高效开发
go-zero代码生成器助你高效开发
|
4月前
|
Java Go API
我用go-zero开发了第一个线上项目
我用go-zero开发了第一个线上项目
|
4月前
|
监控 Serverless Go
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决