1. defer
(1)defer用于将某个方法或语句推迟到当前函数返回的最后一刻执行,一般用于释放某些已分配的资源。函数返回的最后一刻指的是,return语句更新返回值变量之后,函数返回之前,所以defer语句甚至可用于修改函数的返回值(函数头部命名了返回值的情况)。
(2)若defer语句中嵌套了多层函数调用,只是最后一层函数调用才延后执行,其他都按代码执行顺序执行,例如:defer un(trace("b")),先按代码执行顺序执行trace("b"),假设返回值为ret,在函数返回前的最后一刻再执行un(ret)。
(3)defer语句一定会执行,即使发生了panic;defer一定是函数返回的最后一刻才执行,除非遇到panic,才会先执行defer,再执行panic。
(4)若存在多个return分支,且每个return语句之前都需要执行某些同样的操作,则使用defer语句可以避免重复写同样的代码。
(5)当有多个defer行为被注册时,它们会按注册的先后顺序逆序执行(类似栈,后进先出)。

2. panic
(1)Go语言的panic机制类似其他语言的异常,但panic会引起程序的崩溃,一般用于严重错误,大部分错误都应该使用Go语言提供的错误机制,而不是panic。
(2)可使用panic()函数手动触发panic。
(3)当panic发生时,程序会中断运行,并立即执行在当前goroutine中被延迟的所有函数(defer机制),最后程序崩溃,输出错误信息,以及发生panic时的函数调用堆栈跟踪信息,为问题定位提供依据。

3. recover
(1)Go语言提供了内置函数recover(),一般在defer语句中调用,用于捕获panic异常,使程序从panic中回复,并返回panic value。
(2)导致panic异常的函数不会继续运行,但是能正常返回,这意味着调用recover()的函数的上一级调用者可以继续往下执行代码,而不是中断程序运行。
(3)利用recover处理panic时,defer必须在panic之前声明,否则当panic时,recover无法捕获到panic。

4. 一个实例

package main

import (
"fmt"
) func main() {
defer func() { fmt.Println(1) }()
fmt.Println(2)
defer func() { fmt.Println(3) }()
defer_call1()
fmt.Println(4)
} func defer_call1() {
defer func() { fmt.Println("A") }()
fmt.Println("B")
/*
defer func() {
fmt.Println("C")
err := recover()
if err != nil {
fmt.Println(err)
}
fmt.Println("D")
}()
*/
defer func() { fmt.Println("E") }()
defer_call2()
fmt.Println("F")
} func defer_call2() {
defer func() { fmt.Println("a") }()
defer func() { fmt.Println("b") }()
defer func() { fmt.Println("c") }()
fmt.Println("d")
panic("触发异常1")
panic("触发异常2")
fmt.Println("e")
}

(1)直接运行输出:

(2)去掉注释的recover相关代码,运行输出:

defer、panic和recover的更多相关文章

  1. GOLANG错误处理最佳方案errors wrap, Defer, Panic, and Recover

    Simple error handling primitives:        https://github.com/pkg/errors Defer, Panic, and Recover:    ...

  2. 15 Defer, Panic, and Recover

    Defer, Panic, and Recover 4 August 2010 Go has the usual mechanisms for control flow: if, for, switc ...

  3. Golang 入门系列(十四)defer, panic和recover用法

    以前讲过golang 的基本语法.但是,只是讲了一些基础的语法,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863 ...

  4. 6.Go-错误,defer,panic和recover

    6.1.错误 Go语言中使用builtin包下error接口作为错误类型 Go语言中错误都作为方法/函数的返回值 自定义错误类型 //Learn_Go/main.go package main imp ...

  5. go语言defer panic recover用法总结

    defer defer是go提供的一种资源处理的方式.defer的用法遵循3个原则 在defer表达式被运算的同时,defer函数的参数也会被运算.如下defer的表达式println运算的同时,其入 ...

  6. panic和recover的使用规则

    转自个人博客 chinazt.cc 在上一节中,我们介绍了defer的使用. 这一节中,我们温习一下panic和recover的使用规则. 在golang当中不存在tye ... catch 异常处理 ...

  7. Go语言异常处理defer\panic\recover

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  8. 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...

  9. go语言中使用defer、panic、recover处理异常

    go语言中的异常处理,没有try...catch等,而是使用defer.panic.recover来处理异常. 1.首先,panic 是用来表示非常严重的不可恢复的错误的.在Go语言中这是一个内置函数 ...

  10. Go基础系列:defer、panic和recover

    defer关键字 defer关键字可以让函数或语句延迟到函数语句块的最结尾时,即即将退出函数时执行,即便函数中途报错结束.即便已经panic().即便函数已经return了,也都会执行defer所推迟 ...

随机推荐

  1. 漫谈五种IO模型

    阅读目录 1 基础知识回顾 2 I/O模式 3 事件驱动编程模型 网络编程里常听到阻塞IO.非阻塞IO.同步IO.异步IO等概念,搞清楚这些概念之前,还得先回顾一些基础的概念. 1 基础知识回顾 注意 ...

  2. 在PHPstorm上安装thinkPHP

    >环境:ubuntu php7.2 phpstorm https://blog.csdn.net/roukmanx/article/details/85646174 https://www.ka ...

  3. pycharm的一个bug,pycharm 在debug时,会运行项目下的所有文件,而不是当前文件

    pycharm的一个bug,pycharm 在debug时,会运行项目下的所有文件,而不是当前文件

  4. Spring MVC (二)

    一.使用 @RequestMapping 映射请求 Spring MVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求 在控制器的类定义以及方法定义处都可以标注 类定义处:提 ...

  5. 多个webView嵌套在UIScrollView里面内存优化

    之前一直纠结在使用UIWebView上,发现加载6个UIWebView占用了290M左右内存,切换时还会增加.后来看到一篇文章:http://blog.csdn.net/kongu/article/d ...

  6. BZOJ 4836: [Lydsy1704月赛]二元运算 分治FFT

    Code: #include<bits/stdc++.h> #define ll long long #define maxn 500000 #define setIO(s) freope ...

  7. 在服务器上给tomcat指定jdk版本

    export JAVA_HOME=/usr/local/jdk1.8 --路径是:Jdk8所在的目录 export CATALINA_OPTS="-Djava.awt.headless=tr ...

  8. (转)CoreDNS介绍

    转:https://www.colabug.com/4171614.html 本文介绍 CoreDNS 相关配置以及验证方法,实验环境为 Kubernetes 1.11,搭建方法参考 kubeadm安 ...

  9. ZOJ 3822 ( 2014牡丹江区域赛D题) (概率dp)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5376 题意:每天往n*m的棋盘上放一颗棋子,求多少天能将棋盘的每行每列都至少有 ...

  10. CAD到ArcGIS相关操作

    1.Ctrl+N(新建图形)→复制原数据,粘贴到原坐标 2.将CAD数据转为矢量数据方法众多,此处将提供三种方法: 方法一:CAD转地理数据库注记 在[ArcToolBox]窗口中,双击[转换工具]→ ...