defer 和追踪

关键字 defer 允许我们推迟到函数返回之前(或任意位置执行 return 语句之后)一刻才执行某个语句或函数(为什么要在返回之后才执行这些语句?因为 return 语句同样可以包含一些操作,而不是单纯地返回某个值)。

关键字 defer 的用法类似于面向对象编程语言 Java 和 C# 的 finally 语句块,它一般用于释放某些已分配的资源。

示例 6.8 defer.go

package main
import "fmt" func main() {
function1()
} func function1() {
fmt.Printf("In function1 at the top\n")
defer function2()
fmt.Printf("In function1 at the bottom!\n")
} func function2() {
fmt.Printf("function2: Deferred until the end of the calling function!")
}

输出:

In Function1 at the top
In Function1 at the bottom!
Function2: Deferred until the end of the calling function!

请将 defer 关键字去掉并对比输出结果。

使用 defer 的语句同样可以接受参数,下面这个例子就会在执行 defer 语句时打印 0

func a() {
i := 0
defer fmt.Println(i)
i++
return
}

当有多个 defer 行为被注册时,它们会以逆序执行(类似栈,即后进先出):

func f() {
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
}

上面的代码将会输出:4 3 2 1 0

关键字 defer 允许我们进行一些函数执行完成后的收尾工作,例如:

  1. 关闭文件流:

    // open a file defer file.Close() (详见第 12.2 节)

  2. 解锁一个加锁的资源

    mu.Lock() defer mu.Unlock() (详见第 9.3 节)

  3. 打印最终报告

    printHeader() defer printFooter()

  4. 关闭数据库链接

    // open a database connection defer disconnectFromDB()

合理使用 defer 语句能够使得代码更加简洁。

使用 defer 语句实现代码追踪

一个基础但十分实用的实现代码执行追踪的方案就是在进入和离开某个函数打印相关的消息,即可以提炼为下面两个函数:

func trace(s string) { fmt.Println("entering:", s) }
func untrace(s string) { fmt.Println("leaving:", s) }

以下代码展示了何时调用两个函数:

示例 6.10 defer_tracing.go:

package main

import "fmt"

func trace(s string)   { fmt.Println("entering:", s) }
func untrace(s string) { fmt.Println("leaving:", s) } func a() {
trace("a")
defer untrace("a")
fmt.Println("in a")
} func b() {
trace("b")
defer untrace("b")
fmt.Println("in b")
a()
} func main() {
b()
}

输出:

entering: b
in b
entering: a
in a
leaving: a
leaving: b

使用 defer 语句来记录函数的参数与返回值——利用了defer是在return后的特性哇!!!

下面的代码展示了另一种在调试时使用 defer 语句的手法(示例 6.12 defer_logvalues.go):

package main

import (
"io"
"log"
) func func1(s string) (n int, err error) {
defer func() {
log.Printf("func1(%q) = %d, %v", s, n, err)
}()
return 7, io.EOF
} func main() {
func1("Go")
}

输出:

Output: 2011/10/04 10:46:11 func1("Go") = 7, EOF

go语言笔记——defer作用DB资源等free或实现调试的更多相关文章

  1. Go 语言笔记

    Go 语言笔记 基本概念 综述 Go 语言将静态语言的安全性和高效性与动态语言的易开发性进行有机结合,达到完美平衡. 设计者通过 goroutine 这种轻量级线程的概念来实现这个目标,然后通过 ch ...

  2. C语言笔记(一)

    笑话一枚:程序员 A:“哥们儿,最近手头紧,借点钱?”程序员 B:“成啊,要多少?”程序员 A:“一千行不?”程序员 B:“咱俩谁跟谁!给你凑个整,1024,拿去吧.” =============== ...

  3. 009-数组-C语言笔记

    009-数组-C语言笔记 学习目标 1.[掌握]数组的声明 2.[掌握]数组元素的赋值和调用 3.[掌握]数组的初始化 4.[掌握]数组的遍历 5.[掌握]数组在内存中的存储 6.[掌握]数组长度计算 ...

  4. 007-函数-C语言笔记

    007-函数-C语言笔记 学习目标 1.[了解]函数的分类 2.[掌握]函数的声明定义和调用 3.[掌握]函数的形参和实参 4.[掌握]带返回值的函数 5.[掌握]全局变量和局部变量 6.[了解]注释 ...

  5. 005-循环结构(上)-C语言笔记

    005-循环结构(上)-C语言笔记 学习目标 1.[掌握]switch-case结构 2.[理解]case语句穿透 3.[理解]Xcode断点调试 4.[理解]while循环结构初体验 5.[掌握]w ...

  6. 004-流程控制-C语言笔记

    004-流程控制-C语言笔记 学习目标 1.[掌握]关系运算符和关系表达式 2.[掌握]逻辑运算符和逻辑表达式 3.[掌握]运算符的优先级和结合性 4.[掌握]if-else if-else结构的使用 ...

  7. 002-IDE的使用与数据类型-C语言笔记

    002-IDE的使用与数据类型-C语言笔记 学习目标 1.[了解]IDE并熟悉Xcode基本使用技巧 2.[理解]C程序的入口和运行流程 3.[理解]变量的声明赋值和一些细节 4.[理解]变量的命名规 ...

  8. 001-iOS开发前奏-C语言笔记

    001-iOS开发前奏-C语言笔记 学习目标 1.[了解]操作系统 2.[了解]应用软件 3.[了解]操作系统的分类和市场占有份额 4.[了解]iOS操作系统 5.[了解]应用软件开发的分类 6.[了 ...

  9. Go语言笔记[实现一个Web框架实战]——EzWeb框架(一)

    Go语言笔记[实现一个Web框架实战]--EzWeb框架(一) 一.Golang中的net/http标准库如何处理一个请求 func main() { http.HandleFunc("/& ...

随机推荐

  1. Deployd的使用

    deployd一个生成后台数据的软件,可以创建json格式的数据,也可以对数据进行增删改查等操作,甚至可以验证登录,简直就是自学好帮手呀,不用后台搞定后台,就用deployd 下载:链接: https ...

  2. 用Docker构建Nginx镜像

    1构建Nginx镜像 1建立工作目录 [root@localhost ]# mkdir 1nginx [root@localhost 1nginx]# cd 1nginx/ [root@localho ...

  3. idea安装及使用

    使用:https://blog.csdn.net/qq_42303709/article/details/81983208 安装教程:https://blog.csdn.net/yl171272518 ...

  4. MYEclipse Available Memory is low 警告 解决方法

    1,  设置Eclipse内存使用情况 修改eclipse根目录下的eclipse.ini文件 -vmargs  //虚拟机设置 -Xms40m -Xmx256m -XX:PermSize=128M ...

  5. Don't make me think [读书笔记] [思维导图]

      <Don't make me think>第3版 内容:解析用户心理,在用户模式.扫描设计.导航设计.主页布局.可用性测试,提出了许多的独到观点及建议. 特色:语言轻松.实在.配有许多 ...

  6. css去掉div的滚动条

    懒得讲原理了,直接贴代码: css部分: .slide-box { margin-top: 200px; display: -webkit-box; overflow-x: scroll; overf ...

  7. 字符串--P1553 数字反转(升级版)

    题目描述 给定一个数,请将该数各个位上数字反转得到一个新数. 这次与NOIp2011普及组第一题不同的是:这个数可以是小数,分数,百分数,整数.整数反转是将所有数位对调:小数反转是把整数部分的数反转, ...

  8. Re0:DP学习之路 Proud Merchants HDU - 3466

    解法 排序+01背包 这里的排序规则用q-p升序排列这里是一个感觉是一个贪心的策略,为什么这样做目前也无法有效的证明或者说出来 然后就是01背包加了一个体积必须大于什么值可以装那么加一个max(p,q ...

  9. 解决Python打包exe控制台无法粘贴问题

    使用pyinstaller打包生成可执行exe文件后,发现启用input()接受键盘输入时窗口无法粘贴也无法右键,找了好久终于找到问题所在: 一是通过右键单击控制台主题边框在弹出的菜单中选择编辑.粘贴 ...

  10. 以位为单位存储标志-共用体-union

    一.程序的结构如下: typedef union _KEYST     {         struct         {             uint8 Key1_Flag :1;//表示第0 ...