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相关代码,运行输出:

最新文章

  1. c#解析xml
  2. ListView具有多种item布局——实现微信对话列
  3. C++ Qt 框架静态编译 操作记录
  4. KEIL编译错误总结:
  5. bootstrap 中是通过写less文件来生成css文件,用什么工具来编写呢?
  6. Excel 窗体控件属性
  7. Linux shell之数组
  8. AndroidStudio旧模板使用方法
  9. spring的常用配置
  10. 一步一步学Vue(九)
  11. Linux进行AES加密每次结果都不一致并且解密失败报错
  12. 07_数据库创建,添加c3p0操作所需的jar包,编写c3p0-config.xml文件,编写User.java,编写jdbcUtils.java实现操作数据库的模板工具类,UserDao编写,Dao
  13. 关于PS的操作
  14. SOA、SOAP、RFC、RPC、IETF
  15. js树形结构-----(BST)二叉树增删查
  16. Hive分区表新增字段及修改表名,列名,列注释,表注释,增加列,调整列顺序,属性名等操作
  17. 关于python logging的 NOTSET 级别
  18. angularjs文档下载
  19. JVM 类加载机制详解
  20. 目标检测之rcnn---开启检测新高度优于dpm

热门文章

  1. cat 合并文件或查看文件内容
  2. 切面AOP的切点@Pointcut用法
  3. django 修改字段后,同步数据库,失败:django.db.utils.InternalError: (1054, "Unknown column 'api_config.project_id_id' in 'field list'")
  4. pandas.DataFrame.drop_duplicates 用法说明
  5. What are the differences between an LES-SGS model and a RANS based turbulence model?
  6. JMeter-性能测试之报表设定的注意事项
  7. Cenos7下nginx+mysql+php环境的搭建
  8. 笨办法学Python(learn python the hard way)--练习程序1-10
  9. 添加对象到 HashSet 里的规则是
  10. node中console自定义样式