『go成长之路』 defer 作用、典型用法以及多个defer调用顺序,附加defer避坑点,拿来吧你
预习内容
- defer 的作用有哪些?
- 多个 defer 的执行顺序是怎样的?
- defer,return,函数返回值 三者之间的执行顺序
defer的作用
go中的defer是延迟函数,一般是用于释放资源或者收尾工作。
由于defer是具有延迟特性且执行动作是在函数return之后,因此作为资源释放作用再好不过。
- 典型例子:释放锁、关闭文件、关闭链接等
// 释放锁
func getValue() {
s.Lock()
defer s.Unlock()
...
}
// 关闭文件
func read() {
f, err := os.OpenFile("filename", os.O_RDWR, os.ModePerm)
defer f.Close()
...
}
// 关闭链接
func connect() {
resp, err := grequests.Get(s.cfg.GateApiCrossMarginUrl, nil)
defer resp.Close()
...
}
// 收尾工作,defer 同时也是函数,可以做很多收尾相关工作
func closeConnection() {
...
defer func() {
file.close()
close(readChan)
}
...
}
- 还有作用就是捕获 panic,这个功能在defer里也是典型用法
func sendChan() {
// 此处捕获 panic 进行 recover 防止程序崩溃
defer func() {
if ok := recover(); ok != nil {
fmt.Println("recover")
}
}()
// 向已经关闭的chan发送数据,此处会引起 panic
dataChan <- "message"
...
}
defer 释放资源『避坑指南』
资源释放动作一定紧跟资源使用(打开、连接)语句,不然defer可能不会被执行到,导致内存泄露
// 关闭文件
func read() error {
f1, err := os.OpenFile("filename", os.O_RDWR, os.ModePerm)
if err != nil {
return err
}
// 此时,defer还没执行到,提前return了,无效defer导致内存泄露
defer f1.Close()
// 正确用法,紧跟资源使用语句
f2, err := os.OpenFile("filename", os.O_RDWR, os.ModePerm)
defer f2.Close()
if err != nil {
return err
}
}
defer 的调用顺序
墙裂建议不要先看后面的介绍做下面的题目,此处先跳过介绍defer调用顺序,看看下面比较典型的对defer顺序判断,你能看出来几个?
func deferFunc1(i int) (t int) {
t = i
defer func() {
t += 1
}()
return t
}
func deferFunc2(i int) int {
t := i
defer func() {
t += 1
}()
return t
}
func deferFunc3(i int) (t int) {
defer func() {
t += i
}()
return 1
}
func deferFunc4() (t int) {
defer func(i int) {
fmt.Println(i)
fmt.Println(t)
}(t)
t = 0
return 1
}
func ExecDeferFunc() {
// 猜猜下面输出的内容和顺序
fmt.Println(deferFunc1(1))
fmt.Println(deferFunc2(1))
fmt.Println(deferFunc3(1))
deferFunc4()
}
猜想结果可能是:2,2,1,0,0 或者 2,2,1,1,1 ?
估计比较模糊的地方应该是函数返回值 和 return value(函数返回值)关系不明确,还有就是对defer产生作用的时机不明确
正文开始!
再次强调defer是延迟函数,执行动作在return之后,defer相当于是将执行动作压入栈中,越是后面的defer越是先执行,执行顺序是LIFO(后进先出)。
特别指出:有函数返回值的则return将结果写入返回值,defer进行收尾,可以看做 return最先执行,然后return将结果存入返回值,最后defer执行
那么基于刚刚的介绍再回头去看得到的『实际结果是:2,1,2,0,1』
复习内容
- defer 用于资源释放和收尾工作
- 多个 defer 调用顺序是 LIFO(后入先出),defer后的操作可以理解为压入栈中
- defer,return,return value(函数返回值) 执行顺序:首先return,其次return value,最后defer。defer可以修改函数最终返回值。
『go成长之路』 defer 作用、典型用法以及多个defer调用顺序,附加defer避坑点,拿来吧你的更多相关文章
- 『NiFi 学习之路』简介
『NiFi 学习之路』简介 『NiFi 学习之路』入门 -- 下载.安装与简单使用 『NiFi 学习之路』资源 -- 资料汇总 『NiFi 学习之路』把握 -- 架构及主要组件 『NiFi 学习之路』 ...
- 『NiFi 学习之路』自定义 —— 组件的自定义及使用
一.概述 许多业务仅仅使用官方提供的组件不能够满足性能上的需求,往往要通过高度可定制的组件来完成特定的业务需求. 而 NiFi 提供了自定义组件的这种方式. 二.自定义 Processor 占坑待续 ...
- 『NiFi 学习之路』使用 —— 主要组件的使用
一.概述 大部分 NiFi 使用者都是通过 NiFi 的 Processor 来实现自己的业务的.因此,我也主要就 NiFi 官方提供的 Porcessor 进行介绍. 二.Processor 如果你 ...
- 『NiFi 学习之路』把握 —— 架构及主要部件
一.概述 通过前面几篇文章的学习,相信你对 NiFi 有了一个基础性的了解. 数据处理和分发系统 是什么概念? NiFi 系统中数据的传递方式是怎样的? NiFi 的重要 Processor 有哪些? ...
- 『NiFi 学习之路』资源 —— 资料汇总
一.概述 由于 NiFi 是一个比较新的开源项目,国内的相关资料少之又少. 加之,大家都知道,国内的那么些个教程,原创都只是停留在初级使用阶段,没有更多深入的介绍. 再者,其余的文章不是东抄抄就是西抄 ...
- 『NiFi 学习之路』入门 —— 下载、安装与简单使用
一.概述 "光说不练假把式." 官网上的介绍多少让人迷迷糊糊的,各种高大上的词语仿佛让 NiFi 离我们越来越远. 实践是最好的老师.那就让我们试用一下 NiFi 吧! 二.安装 ...
- 『王霸之路』从0.1到2.0一文看尽TensorFlow奋斗史
0 序篇 2015年11月,Google正式发布了Tensorflow的白皮书并开源TensorFlow 0.1 版本. 2017年02月,Tensorflow正式发布了1.0.0版本,同时也标志 ...
- Android成长之路-LayoutInflater和inflate的用法
在这里用Tabhost的例子来说明: package cn.csdn.activity; import android.app.TabActivity; import android.os.Bundl ...
- 『TensorFlow2.0正式版』TF2.0+Keras速成教程·零:开篇简介与环境准备
此篇教程参考自TensorFlow 2.0 + Keras Crash Course,在原文的基础上进行了适当的总结与改编,以适应于国内开发者的理解与使用,水平有限,如果写的不对的地方欢迎大家评论指出 ...
随机推荐
- unity调用安卓方法实现安装apk文件(androidx)
原文链接:点击打开 unity想要实现安装apk文件需要与安卓通讯,所以需要自己来实现安卓代码. 第一步先要新建一个安卓项目提供给unity来使用,我这里使用的工具是android studio4.1 ...
- 什么是DDoS黑洞路由?
1. 什么是DDoS黑洞路由? DDoS黑洞路由/过滤(有时称为黑孔)是缓解DDoS攻击的一种对策,网络流量将被路由到"黑洞"中并且丢失.如果在没有特定限制条件下实施黑洞过滤,合法 ...
- 重新整理 .net core 实践篇————网关[三十六]
前言 简单整理一下网关. 正文 在介绍网关之前,介绍一下BFF,BFF全称是Backend For Frontend,它负责认证授权,服务聚合,目标是为前端提供服务. 说的通透一点,就是有没有见过这种 ...
- 使用 CKEditor编辑插件
1, 安装方法 下载CKEditor插件,然后解压到对应的文件中.建议解压到JS文件夹下面的CKEditor这个文件夹下.下载地址 : http://down.chinaz.com/soft/2516 ...
- CRM的职能和主要构成模块探索
CRM客户管理系统是随着互联网的快速发展和信息技术的进步而发展起来的,是企业管理客户关系.优化业务流程的首选.客户关系管理可以存储企业获得的客户信息,方便业务人员随时查看和了解客户需求:客户关系管理可 ...
- AcWing 102. 最佳牛围栏
农夫约翰的农场由 N 块田地组成,每块地里都有一定数量的牛,其数量不会少于1头,也不会超过2000头. 约翰希望用围栏将一部分连续的田地围起来,并使得围起来的区域内每块地包含的牛的数量的平均值达到最大 ...
- UI自动化学习笔记- UnitTest单元测试框架详解
一.UnitTest基本使用 1. UnitTest框架 1.1 什么是框架 说明: 框架英文单词frame 为解决一类事情的功能集合 1.2什么是UnitTest框架 概念:UnitTest是pyt ...
- Adaptive AUTOSAR 学习笔记 2 - 官方文档下载及阅读建议
目前互联网上没有太多的 Adaptive AUTOSAR 的学习资料,官方文档是一个很不错的途径.看过官方文档才发现,目前很多关于 Adaptive AUTOSAR 的文章都是官方文档的简化翻译,不如 ...
- 深入理解Java多线程——ThreadLocal
目录 定义 API 场景分析 场景实验,观察Spring框架在多线程场景的执行情况 10000此请求,单线程 10000次请求,线程数加到100 对c的访问加锁 把c设为ThreadLocal 收集多 ...
- 浅淡fhq_Treap
浅淡 \(fhq\_Treap\) 前言 fhq_Treap \(yyds\)! \(sto\ FHQ\ orz\) 机房大佬们都打的 \(Splay\) 只有蒟蒻打的 \(fhq\) (防火墙)(范 ...