什么是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 :=
defer func() {
fmt.Println(v)
v++
fmt.Println(v)
}()
v +=
}

输出为


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

defer 读写命名的返回值

    这个例子中,defer声明的方法,给命名的返回值自增1

 func doSomething() (rev int) {
defer func() {
rev++
}() return
}

  第6行的return 相当于

return rev = 

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

rev =
// 执行defer方法
rev++
//然后return
return

  所以结果是6

  我把代码做一点点修改

 func doSomething() (rev int) {
v :=
defer func() {
v++
}() return v
}

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

return v 相当于 return rev = v

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

defer 执行顺序

当有多个defer时执行顺序逆向的,后进先出:
func doSomething() {
defer fmt.Println()
defer fmt.Println()
}
会先输出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

 

golang 详解defer的更多相关文章

  1. 【Golang详解】go语言中并发安全和锁

    go语言中并发安全和锁 首先可以先看看这篇文章,对锁有些了解 [锁]详解区分 互斥锁.⾃旋锁.读写锁.乐观锁.悲观锁 Mutex-互斥锁 Mutex 的实现主要借助了 CAS 指令 + 自旋 + 信号 ...

  2. Golang——详解Go语言代码规范

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Golang专题的第二篇,我们来看看Go的语言规范. 在我们继续今天的内容之前,先来回答一个问题. 有同学在后台问我,为什么说Gola ...

  3. Golang入门教程(十三)延迟函数defer详解

    前言 大家都知道go语言的defer功能很强大,对于资源管理非常方便,但是如果没用好,也会有陷阱哦.Go 语言中延迟函数 defer 充当着 try...catch 的重任,使用起来也非常简便,然而在 ...

  4. 详解golang net之netpoll

    golang版本1.12.9:操作系统:readhat 7.4 golang的底层使用epoll来实现IO复用.netPoll通过pollDesc结构体将文件描述符与底层进行了绑定.netpoll实现 ...

  5. Golang官方log包详解

    Golang官方log包详解 以下全是代码, 详解在注释中, 请从头到尾看 // Copyright 2009 The Go Authors. All rights reserved. // Use ...

  6. python golang中grpc 使用示例代码详解

    python 1.使用前准备,安装这三个库 pip install grpcio pip install protobuf pip install grpcio_tools 2.建立一个proto文件 ...

  7. Go 延迟函数 defer 详解

    Go 延迟函数 defer 详解 Go 语言中延迟函数 defer 充当着 try...catch 的重任,使用起来也非常简便,然而在实际应用中,很多 gopher 并没有真正搞明白 defer.re ...

  8. GoLang基础数据类型--->字典(map)详解

    GoLang基础数据类型--->字典(map)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是 ...

  9. golang格式化输出-fmt包用法详解

    golang格式化输出-fmt包用法详解 注意:我在这里给出golang查询关于包的使用的地址:https://godoc.org    声明: 此片文章并非原创,大多数内容都是来自:https:// ...

随机推荐

  1. Ubuntu配置Nginx虚拟主机和支持ThinkPHP

    [Nginx配置虚拟主机] 每一个 server { listen       80;         server_name  www.a.com; ..... } 就表示一台虚拟域名, 然后对应的 ...

  2. Oracle,Sql,procedure 感觉自己写的很棒的一个存储过程

    感觉自己写的很棒的一个Oracle存储过程,(其实想说很叼^,^). 集成了一堆操作数据的功能(至少几十), 包括存储过程执行异常信息输出帮助诊断. 亮点很多, 比如`over(partition b ...

  3. angular2-qrcode (转)

    插件选择 angular2-qrcode npm install angular2-qrcode --savecnpm install angular2-qrcode --save 参考github ...

  4. HashMap中的散列函数、冲突解决机制和rehash

    一.概述 散列算法有两个主要的实现方式:开散列和闭散列,HashMap采用开散列实现. HashMap中,键值对(key-value)在内部是以Entry(HashMap中的静态内部类)实例的方式存储 ...

  5. Spring中的@scope注解

    默认是单例模式,即scope="singleton".另外scope还有prototype.request.session.global session作用域.scope=&quo ...

  6. python爬虫提取冰与火之歌五季的种子

    # -*- encoding:utf-8 -*- import requests import re import sys reload(sys) sys.setdefaultencoding(&qu ...

  7. 阿里云ECS重置磁盘到SSH登录

    1.登录阿里云(www.aliyun.com) -- > 控制台: 2.点击左边的"云服务器ECS": 3.点击上面"第二步",进入页面之后,点击&quo ...

  8. 设置TCP_USER_TIMEOUT参数来判断tcp连接是否断开

    [TOC] 1. bug描述 前段时间遇到这样的一个问题,openstack一个控制节点宕机后,在宕机后一段时间内创建的虚拟机,一直卡在创建中的状态.有的甚至要等到16分钟之后虚拟机才会切换到下一个状 ...

  9. 如何更改Ubuntu的root密码

    安装Ubuntu系统时,只提示了设定用户密码,该密码可用于普通用户暂时获取root的权限,执行一些需要root权限的操作,而没有要求我们设置root密码,在需要用到root密码时,却想不起来,很尴尬啊 ...

  10. NLP︱词向量经验总结(功能作用、高维可视化、R语言实现、大规模语料、延伸拓展)

    R语言由于效率问题,实现自然语言处理的分析会受到一定的影响,如何提高效率以及提升词向量的精度是在当前软件环境下,比较需要解决的问题. 笔者认为还存在的问题有: 1.如何在R语言环境下,大规模语料提高运 ...