对于golang的defer,我们已经知道,defer定义的语句可以延后到函数返回时执行。

经常用在文件的关闭,锁的释放等场景中。而且defer定义的语句即使遇到panic也会执行。这样,可以执行必要的清理工作,甚至使用recover()捕获异常。

以前使用defer经常这样用:

defer close()

或者

defer func(){
//do something...
}()

本文介绍defer使用函数返回值(也是函数)作为延后执行内容时的情况。

请看例子代码:

package main

import (
"fmt"
) func main(){
a()
} func a() {
defer b()() fmt.Println("a...")
} func b() func() {
fmt.Println("b...")
return func(){
fmt.Println("last...")
}
}

这个例子很简单,只有几行代码。

对于defer的认识,

以前的误解是:

defer b()()中的b()也是延后执行的。

而实际情况是:

执行defer b()()语句时,会去执行b(), 而b()返回的函数延后执行。

输出的结果是:

b...
a...
last...

这种用法已经在《Go语言圣经》中提到,具体例子代码如下:

//gopl.io/ch5/trace

func bigSlowOperation() {
defer trace("bigSlowOperation")() // don't forget the extra parentheses
// ...lots of work... time.Sleep(10 * time.Second) // simulate slow operation by sleeping
} func trace(msg string) func() {
start := time.Now()
log.Printf("enter %s", msg)
return func() {
log.Printf("exit %s (%s)", msg,time.Since(start))
}
}

defer定义时,开始计时,等bigSlowOperation结束时,执行延后函数,计算执行的耗时。

golang defer 延后执行什么的更多相关文章

  1. innerHTML 延后执行?

    时常会觉得 innerHTML 可能有延后执行的情况,比如下面代码: document.body.innerHTML = 'something'; alert('something else'); 明 ...

  2. linux 延后执行

    设备驱动常常需要延后一段时间执行一个特定片段的代码, 常常允许硬件完成某个任务. 在这一节我们涉及许多不同的技术来获得延后. 每种情况的环境决定了使用哪种技术最好; 我们全都仔细检查它们, 并且指出每 ...

  3. 延宕执行,妙用无穷,Go lang1.18入门精炼教程,由白丁入鸿儒,Golang中defer关键字延迟调用机制使用EP17

    先行定义,延后执行.不得不佩服Go lang设计者天才的设计,事实上,defer关键字就相当于Python中的try{ ...}except{ ...}finally{...}结构设计中的finall ...

  4. 泛函编程(11)-延后计算-lazy evaluation

    延后计算(lazy evaluation)是指将一个表达式的值计算向后拖延直到这个表达式真正被使用的时候.在讨论lazy-evaluation之前,先对泛函编程中比较特别的一个语言属性”计算时机“(s ...

  5. 拒绝滥用golang defer机制

    原文链接 : http://www.bugclosed.com/post/17 defer机制 go语言中的defer提供了在函数返回前执行操作的机制,在需要资源回收的场景非常方便易用(比如文件关闭, ...

  6. 读书笔记_Effective_C++_条款二十六:尽可能延后变量定义式的出现时间

    这个条款从字面意思还是很好理解的,就是在使用这个变量前才去定义,而不是很早就定义了它,而在很后面的时候才去使用.这个条款只适用于对变量声明位置没有要求的语言,比如C++.对于像C或者一些脚本语言,语法 ...

  7. iOS UITableView reloadData 刷新结束后执行后续操作

    如果在reloadData后需要立即获取tableview的cell.高度,或者需要滚动tableview. 如果直接在reloadData后执行代码是有可能出问题的,比如indexPath为nil等 ...

  8. Go ---- defer 和 return 执行的先后顺序

    Go 中 defer 和 return 执行的先后顺序 多个defer的执行顺序为“后进先出”: defer.return.返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入 ...

  9. databinding 填坑 绑定动作是延后生效

    binding = FragmentNewsMainLayout750Binding.inflate(inflater); homePageViewModel = new HomePageViewMo ...

随机推荐

  1. 直通BAT必考题系列:JVM性能调优的6大步骤,及关键调优参数详解

    JVM内存调优 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数. 1.Full GC 会对整个堆进行整理,包括Young.Tenured和Perm.Full GC因为需要对 ...

  2. rabbitmq一键部署脚本

    1.新建一个名字叫 auto_install_rabbitmq.sh  的文件 2.将下面脚本拷贝到文件中,具体操作步骤在注释里面 #环境 linux #一键安装rabitmq,在linux环境中使用 ...

  3. 2019-2020-1 20199319《Linux内核原理与分析》第七周作业

    进程的描述和进程的创建 进程的描述 1.操作系统内核实现操作系统的三大管理功能: 进程管理 内存管理 文件系统. 其中最核心的功能是进程管理. 2.对进程的描述:在操作系统原理中,通过进程控制块PCB ...

  4. cmd 创建并写入文件

    一.建立空文件的几种方法1.cd.>a.txtcd.表示改变当前目录为当前目录,即等于没改变:而且此命令不会有输出.>表示把命令输出写入到文件.后面跟着a.txt,就表示写入到a.txt. ...

  5. CRM项目讲解和django知识点回顾

    今天想把之前写的CRM项目梳理下,顺便回顾一下djiango的部分重要知识. 1.登录页面(包含简单验证码) 首先来看下CRM的登录页面,样式啥的不重要,大家可以去jquery ui的网站上或者其他地 ...

  6. Tomcat部署多个Springboot项目报错 InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat

    在一个tomcat服务器下部署了多个采用阿里druid作为数据连接池,结果启动报错.原因是不能在一个tomcat服务器下不能直接部署多个druid作为数据连接池的项目,需要配置. 解决办法: 在spr ...

  7. js 动态加载js 并执行

    function loadJS(url, success) { var domScript = document.createElement('script'); domScript.src = ur ...

  8. head first 设计模式笔记8-模板方法模式

    模板设计模式:就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现. 优点:使用模板方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求. 缺点:如果算法骨架有修改的 ...

  9. jquery keypress() 方法 语法

    jquery keypress() 方法 语法 作用:keypress 事件与 keydown 事件类似.当按钮被按下时,会发生该事件.它发生在当前获得焦点的元素上.不过,与 keydown 事件不同 ...

  10. java web文件上传功能实现

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...