关键字 defer ⽤于延迟一个函数或者方法(或者当前所创建的匿名函数)的执行。

注意,defer语句只能出现在函数或方法的内部。

defer语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。

释放资源的defer应该直接跟在请求资源的语句后。

func main() {
fmt.Println("this is a test")
defer fmt.Println("this is a defer") //main结束前调用 /*
运行结果:
this is a test
this is a defer
*/
}

多个defer

会按栈的顺序,后进先出。

func test(x int) {
fmt.Println(100 / x)//x为0时,产生异常
} func main() {
defer fmt.Println("aaaaaaaa")
defer fmt.Println("bbbbbbbb") defer test(0) defer fmt.Println("cccccccc")
/*
运行结果:
cccccccc
bbbbbbbb
aaaaaaaa
panic: runtime error: integer divide by zero
*/
}

panic也挡不出defer的执行。所以可以拿来做兜底。

但是要注意把兜底的defer放在最上面。

package main

import "fmt"

func test(x int) {
defer fmt.Println("我要崩溃了")
fmt.Println(100 / x) //x为0时,产生异常
} func main() {
defer func() {
recover()
fmt.Println("没事,我兜住了")
}() defer test(0) defer fmt.Println("aaaaaaaa")
defer fmt.Println("bbbbbbbb") /*
运行结果:
bbbbbbbb
aaaaaaaa
我要崩溃了
没事,我兜住了
*/
}

如果panic在上面呢?

package main
import "fmt" func main() { panic(11) //这里就直接崩溃退出了,兜不住的。 defer func() {
recover()
fmt.Println("没事,我兜住了")
}() }

【Go语言学习笔记】Go的defer的更多相关文章

  1. GO语言学习笔记(一)

    GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...

  2. Go语言学习笔记(1)——顺序编程

    Go语言学习笔记这一堆主要是<Go语言编程>(人民邮电出版社)的读书笔记.中间会穿插一些零碎的点,比如源码学习之类的.大概就是这样吧. 1. 顺序编程 1.1 变量 变量的声明: var ...

  3. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  4. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  5. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

  6. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  7. Go语言学习笔记十三: Map集合

    Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ...

  8. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  9. Go语言学习笔记十一: 切片(slice)

    Go语言学习笔记十一: 切片(slice) 切片这个概念我是从python语言中学到的,当时感觉这个东西真的比较好用.不像java语言写起来就比较繁琐.不过我觉得未来java语法也会支持的. 定义切片 ...

  10. Go语言学习笔记十: 结构体

    Go语言学习笔记十: 结构体 Go语言的结构体语法和C语言类似.而结构体这个概念就类似高级语言Java中的类. 结构体定义 结构体有两个关键字type和struct,中间夹着一个结构体名称.大括号里面 ...

随机推荐

  1. Jmeter系列(15)- 常用断言之大小断言

    大小断言 大小断言验证响应数据size大小,它的作用范围有主Sample与子Sample:适用场景,判断附件下载的大小,比如项目安装包 完整响应:全部响应信息 响应头:响应头信息,比如http协议的头 ...

  2. Java基础系列(35)- 数组声明创建

    数组声明创建 首先必须声明数组变量,才能在程序中使用数组.下面是声明数组变量的语法: dataType[] arrayRefVar; //首选的方法 或 dataType arrayRefVar[]; ...

  3. Java基础系列(31)- 可变参数

    可变参数 JDK1.5开始,Java支持传递同类型的可变参数给一个方法 在方法声明中,在指定参数类型后加一个省略号(...) 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数.任何普通的参数 ...

  4. Python简单算法的实现

    #coding=utf-8 #!/usr/bin/python def GCD(a,b): """ :求两个数的最大公约数 :param a: :param b: :re ...

  5. P3649-[APIO2014]回文串【PAM】

    正题 题目链接:https://www.luogu.com.cn/problem/P3649 题目大意 一个字符串,求最大的回文串长度×出现次数 解题思路 构建出\(\text{PAM}\)然后统计一 ...

  6. CF438E-The Child and Binary Tree【生成函数】

    正题 题目链接:https://www.luogu.com.cn/problem/CF438E 题目大意 每个节点有\(n\)个权值可以选择,对于\(1\sim m\)中的每个数字\(k\),求权值和 ...

  7. 千位分隔符的JS实现

    $.extend({ //千位分割符 MoneySeparator: function numFormat(num){ if(num==null){ return num; }else { num=n ...

  8. 调试器地址出现大小端紊乱,引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。

    今天在编写一系列新增需求代码后,开始调试代码 发现上个版本正常可运行的代码出现了:引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突. 上个版本数代码 ...

  9. java课堂测试2第一阶段:方法运用

    package test2; import java.util.*; public class Test2 { public static int generateRandom(int fanwei) ...

  10. AT3950 [AGC022E] Median Replace

    题目传送门 Description 有一个长度为 \(n\) 的 \(01\) 串,里面有一些还没有确定,我们标记为 ? .可以进行若干次操作,每次操作可以把三个相邻的数替换成它们的中位数.问有多少种 ...