博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang 详解defer
阅读量:7043 次
发布时间:2019-06-28

本文共 1720 字,大约阅读时间需要 5 分钟。

什么是defer

defer用来声明一个延迟函数,把这个函数放入到一个栈上, 当外部的包含方法return之前,返回参数到调用方法之前调用,也可以说是运行到最外层方法体的"}"时调用。我们经常用他来做一些
资源的释放,比如关闭io操作
 
func doSomething(fileName string) {    file,err := os.Open(fileName)    if err != nil {    panic(err)    }    defer file.Close()}

 

defer 可以保证方法可以在外围函数返回之前调用。有点像其他言的 try finally
try{}finally{}

 

defer 读写外部变量

  defer声明的函数读写外部变量,和闭包差不多。比如下面的代码

func doSomething() {    v := 10    defer func() {        fmt.Println(v)        v++        fmt.Println(v)    }()    v += 5}

输出为

1516

  就像闭包一样,如果不是defer函数方法内的变量会向上一层函数访问变量,重新做计算。

defer 读写命名的返回值

    这个例子中,defer声明的方法,给命名的返回值自增1
 
1 func doSomething() (rev int) {2     defer func() {3         rev++4     }()5 6     return 57 }

  第6行的return 相当于

return rev = 5

  defer 声明的匿名函数会在return 之前执行,相当于

rev = 5// 执行defer方法rev++//然后returnreturn

  所以结果是6

  我把代码做一点点修改

1 func doSomething() (rev int) {2     v := 103     defer func() {4         v++5     }()6 7     return v8 }

  第7行返回的是局部变量v.   

return v 相当于 return rev = v

  defer 函数里是对局部变量v的操作,所以与返回的rev没有关系。所有执行的结果是:10

defer 执行顺序

当有多个defer时执行顺序逆向的,后进先出:
func doSomething() {    defer fmt.Println(1)    defer fmt.Println(2)}

 

会先输出2,再输出1
 

 defer 处理异常

  panic抛出异常后,如果不处理应用程序会崩溃。为了防止程序崩溃,我们可以在defer的函数里使用recover来捕获中异常:
func doSomething() {    defer func() {        if err := recover(); err != nil {            fmt.Print(err)        }            }()    fmt.Println("Running...")    panic("run error")}

输出:

Running...run error

recover 会捕获panic的异常。我再把代码做一点点修改:

func doSomething() {    defer func() {        if err := recover(); err != nil {            fmt.Print(err)        }            }()    defer func() {        panic("defer error")    }()    fmt.Println("Running...")    panic("run error")}

 

输出结果

Running...defer error

因为 recover()只捕获最后一次panic

转载地址:http://uweal.baihongyu.com/

你可能感兴趣的文章
分享一个基于 Node.js 的 Web 开发框架 - Nokitjs
查看>>
mysql 简单全量备份和快速恢复
查看>>
全面解密QQ红包技术方案:架构、技术实现、移动端优化、创新玩法等 ...
查看>>
Python进阶:设计模式之迭代器模式
查看>>
Java是如何实现平台无关性的
查看>>
线上马戏团对接协议部分介绍
查看>>
一文纵览自然语言生成的发展
查看>>
常见seo骗局
查看>>
RNA药物研发初创公司Panorama Medicine完成370万美元种子轮融资 ...
查看>>
hanlp提取文本关键词的使用方法记录
查看>>
SpringBoot - 日志配置
查看>>
Python零基础学习笔记(十四)—— while语句
查看>>
swap释放过程浅析
查看>>
linux gzip
查看>>
Python知识点:lambda, map, filter
查看>>
zabbix snmp模板通用
查看>>
RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势
查看>>
Angular prod打包编译异常
查看>>
RPG游戏开发基础教程
查看>>
起落落落之后,区块链商用化的春天在哪儿?
查看>>