GO语言中间的derfer
defer
Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。当函数执行到最后时,这些defer语句会按照逆序执行, 最后该函数返回。特别是当你在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前你需要关闭相应的资源,不然很容易造成资源泄露等问题。如下代码 所示,我们一般写打开一个资源是这样操作的:
func ReadWrite() bool {
file.Open("file")
// 做一些工作
if failureX {
file.Close()
return false
}
if failureY {
file.Close()
return false
}
file.Close()
return true
}
我们看到上面有很多重复的代码,Go的defer有效解决了这个问题。使用它后,不但代码量减少了很多,而且程序变得更优雅。在defer后指定的函数会在函数退出前调用。
func ReadWrite() bool {
file.Open("file")
defer file.Close()
if failureX {
return false
}
if failureY {
return false
}
return true
}
如果有很多调用defer,那么defer是采用后进先出模式,所以如下代码会输出4 3 2 1 0
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
defer 给我的第一印象就是,类似Java中的
try {
}finally {
}
我目前的理解就是,在函数块中使用defer,就是函数对应的有一个栈空间,先进后出。需要函数结束后调用栈,来出发defer操作。
如果,一个对象的创建,很消耗内存,需要及时关闭,defer无法像try finnaly哪样准确。
- package main
- import "fmt"
- import "time"
- type User struct {
- username string
- }
- func (this *User) Close() {
- fmt.Println(this.username, "Closed !!!")
- }
- func main() {
- u1 := &User{"jack"}
- defer u1.Close()
- u2 := &User{"lily"}
- defer u2.Close()
- time.Sleep(10 * time.Second)
- fmt.Println("Done !")
- }
- [vicky@localhost goroutine]$
[vicky@localhost goroutine]$ go run deferTest1.go
Done !
lily Closed !!!
jack Closed !!!
[vicky@localhost goroutine]$
实际上,线程Sleep的10秒,u1,和u2早就可以Close()了,但却需要依赖main()函数的结束,才能defer执行。
那么尝试给defer添加内部代码区:
- package main
- import "fmt"
- import "time"
- type User struct {
- username string
- }
- func (this *User) Close() {
- fmt.Println(this.username, "Closed !!!")
- }
- func main() {
- {
- // 即便加了代码快范围,依旧也要主函数体结束才执行defer
- u1 := &User{"jack"}
- defer u1.Close()
- }
- u2 := &User{"lily"}
- defer u2.Close()
- time.Sleep(10 * time.Second)
- fmt.Println("Done !")
- }
Done !
lily Closed !!!
jack Closed !!!
[vicky@localhost goroutine]$
依旧defer的执行在Done!后。那么如何才能达到try finally 哪样准确的Close呢?
- package main
- import "fmt"
- import "time"
- type User struct {
- username string
- }
- func (this *User) Close() {
- fmt.Println(this.username, "Closed !!!")
- }
- func main() {
- u1 := &User{"jack"}
- f(u1) // 这样的方式,u1才会不依赖main函数的执行
- // 这样的方式,u2也不会依赖main函数的执行
- u2 := &User{"lily"}
- // m := func() {
- // defer u2.Close()
- // // u2 do somthing
- // }
- // m()<pre name="code" class="plain"> func() {
- defer u2.Close()
- // u2 do somthing
- }()</pre> time.Sleep(10 * time.Second) fmt.Println("Done !")}func f(u *User) { defer u.Close() // u1 do gomething}
[vicky@localhost goroutine]$ go run deferTest3.go
jack Closed !!!
lily Closed !!!
Done !
这样的使用方式,视乎不太合理,但却有存在的必要性。大多数情况下,可以用于 u1,u2 之类非常消耗内存,或者cpu,其后执行时间过程且没有太多关联的情况。既保留了defer的功能特性,也满足范围精确控制的条件!
GO语言中间的derfer的更多相关文章
- Go语言性能优化
原文:http://bravenewgeek.com/so-you-wanna-go-fast/ 我曾经和很多聪明的人一起工作.我们很多人都对性能问题很痴迷,我们之前所做的是尝试逼近能够预期的(性能) ...
- C语言 · 高精度加法
问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一个数组A ...
- Windows server 2012 添加中文语言包(英文转为中文)(离线)
Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...
- iOS开发系列--Swift语言
概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...
- C语言 · Anagrams问题
问题描述 Anagrams指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母(不区分大小写)所出现的次数都是相同的.例如,"Unclear"和"Nuclear ...
- C语言 · 字符转对比
问题描述 给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一: 1:两个字符串长度不等.比如 Beijing 和 Hebei 2:两个字符串不仅长度相 ...
- JAVA语言中的修饰符
JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...
- Atitit 项目语言的选择 java c#.net php??
Atitit 项目语言的选择 java c#.net php?? 1.1. 编程语言与技术,应该使用开放式的目前流行的语言趋势1 1.2. 从个人职业生涯考虑,java优先1 1.3. 从项目实际来 ...
- 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】
说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...
随机推荐
- 【转】MYSQL入门学习之三:全文本搜索
转载地址:http://www.2cto.com/database/201212/173873.html 一.理解全文本搜索 www.2cto.com 1.MyISAM支持全文本搜索,而Inn ...
- 周赛-Killing Monsters 分类: 比赛 2015-08-02 09:45 3人阅读 评论(0) 收藏
Killing Monsters Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- shell脚本之if语句
一.前言 结构化编程中,主要有三种结构:顺序.分支.循环.由此可见分支判断的重要性. 而且在shell编程中往往会遇到进行判断的情况,比如:判断文件是否存在.目录是否存在等等. 二.if语句的结构 i ...
- 网站性能优化之CSS无图片技术:三角形
1.使用CSS无图片技术,可以总结得到以下三个优点: 减少请求资源的大小: 减少http的请求个数: 提高可维护性. 一.CSS无图片技术,微博中有哪些实际应用呢? 通过上面的展示,我们可以看到,无图 ...
- 注册页面的验证 WEB的三级联动
1.js中window.onload = function () {};表示当页面都加载完了之后才走里面的内容. 2.当函数中遇到return时,会跳出函数,return后面的内容不再继续进行,就是后 ...
- CentOS6.5下安装wine OK
这篇文章主要记录了如何在CentOS 6.5上安装Wine 1.7.24开发版 1.安装需要的软件包 # yum groupinstall ‘Development Tools‘ # yum inst ...
- android source
h1 { margin-bottom: 0.21cm } h1.western { font-family: "Liberation Sans", sans-serif; font ...
- 进程间通信之打开关闭一个exe文件
一.打开 1.WinExec("F:\\QQ\\Bin\\QQ.exe",SW_SHOW); 注意:'\'需要改成'\\',阻塞 2. STARTUPINFO si; PROCES ...
- C#读写本地ini
//读写INI public class GF_INI { [DllImport("kernel32")] private static extern long WritePriv ...
- CSS3弹力球
如下代码实现方块在限定区域内不停弹跳. <!DOCTYPE html> <html> <head> <style> div { width:100px; ...