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 ————————— ...
随机推荐
- js笔记---拖动元素
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- class打包成exe方式
首先运行dos命令 jar -cvf **.jar *.class 把所有文件打包成jar包 用解压器打开jar包 打开meta-inf文件夹 打开用记事本打开main.mf文件 增加语句Main-C ...
- 20150813 Asp.net 关闭子窗体 刷新Tree控件
主窗体************************************************************************************ using System ...
- Find The Multiple 分类: 搜索 POJ 2015-08-09 15:19 3人阅读 评论(0) 收藏
Find The Multiple Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21851 Accepted: 8984 Sp ...
- 第十二届浙江省大学生程序设计大赛-May Day Holiday 分类: 比赛 2015-06-26 14:33 10人阅读 评论(0) 收藏
May Day Holiday Time Limit: 2 Seconds Memory Limit: 65536 KB As a university advocating self-learnin ...
- Fibonacci Again 分类: HDU 2015-06-26 11:05 13人阅读 评论(0) 收藏
Fibonacci Again Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- 新注册域名greenopen.site,向专业道路进军
新注册域名greenopen.site,向专业道路进军,欢迎访问!届时可以通过 greenopen.site jsxyhelu.github.io 或者jsxyhelu.cnblogs.com 访问本 ...
- 为Apache配置虚拟机Virtual Host
配置虚拟机最少需要修改两个文件,即httpd-vhosts.conf 和 hosts (记住修改任何配置前先备份哦,这才是个好习惯) 第一步,修改httpd-vhosts.conf文件, 文件路径 \ ...
- masonry插件和infinitescroll插件实现无刷新无分页完美瀑布流
地址有:http://www.17sucai.com/pins/2657.html 如果你善于发现美,如果你善于观察新鲜的事物,如果你是一名有爱的前端攻城师或设计尸,那么你一定不会对下面图片中的结构感 ...
- request、response 中文乱码问题与解决方式
request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码: response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码: ...