defer(延迟执行语句)

多个延迟执行语句的处理顺序

package main
import (
"fmt"
)
func main() {
fmt.Println("defer begin")
// 将defer放入延迟调用栈
defer fmt.Println(1)
defer fmt.Println(2)
// 最后一个放入, 位于栈顶, 最先调用
defer fmt.Println(3)
fmt.Println("defer end")
}

结果分析如下:

  • 代码的延迟顺序与最终的执行顺序是反向的。
  • 延迟调用是在 defer 所在函数结束时进行,函数结束可以是正常返回时,也可以是发生宕机时。

使用延迟执行语句在函数退出时释放资源

处理业务或逻辑中涉及成对的操作是一件比较烦琐的事情,比如打开和关闭文件、接收请求和回复请求、加锁和解锁等。在这些操作中,最容易忽略的就是在每个函数退出处正确地释放和关闭资源。
defer 语句正好是在函数退出时执行的语句,所以使用 defer 能非常方便地处理资源释放问题。

panic——程序终止运行

package main
func main() {
panic("crash")
}

在宕机时触发延迟执行语句

当 panic() 触发的宕机发生时,panic() 后面的代码将不会被运行,但是在 panic() 函数前面已经运行过的 defer 语句依然会在宕机发生时发生作用,参考下面代码

package main
import "fmt"
func main() {
defer fmt.Println("宕机后要做的事情1")
defer fmt.Println("宕机后要做的事情2")
panic("宕机")
}

输出结果为:

宕机后要做的事情2
宕机后要做的事情1
panic: 宕机 goroutine 1 [running]:
main.main()
F:/src/tester/main.go:8 +0x1a4

recover

无论是代码运行错误由 Runtime 层抛出的 panic 崩溃,还是主动触发的 panic 崩溃,都可以配合 defer 和 recover 实现错误捕捉和恢复,让代码在发生崩溃后允许继续运行。

defer func() {
if r:= recover();r != nil{
log.Printf("Runtime error caught :%v",r)
}
}() foo()

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

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

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

  2. Golang错误处理函数defer、panic、recover、errors.New介绍

    在默认情况下,当发生错误(panic)后,程序就会终止运行 如果发生错误后,可以捕获错误,并通知管理人员(邮件或者短信),程序还可以继续运行,这当然无可厚非 errors.New("错误信息 ...

  3. 理解Defer、Panic和Recover

    刚开始的时候理解如何使用Defer和Recover有一点怪异,尤其是使用了try/catch块的时候.有一种模式可以在Go中实现和try/catch语句块一样的效果.不过之前你需要先领会Defer.P ...

  4. Golang 高效实践之defer、panic、recover实践

    前言 我们知道Golang处理异常是用error返回的方式,然后调用方根据error的值走不同的处理逻辑.但是,如果程序触发其他的严重异常,比如说数组越界,程序就要直接崩溃.Golang有没有一种异常 ...

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

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

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

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

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

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

  8. go chapter 5 - 异常处理 error、panic、recover

    https://blog.csdn.net/tennysonsky/article/details/78946265 error(不中断).panic(中断).recover(拦截中断  类似于 ca ...

  9. defer、panic和recover

    1. defer(1)defer用于将某个方法或语句推迟到当前函数返回的最后一刻执行,一般用于释放某些已分配的资源.函数返回的最后一刻指的是,return语句更新返回值变量之后,函数返回之前,所以de ...

  10. [Golang]-4 错误处理、Panic、Defer

    目录 错误和异常 案例 Panic Defer 使用 defer+recover 来处理错误 参考文章: Go 语言使用一个独立的·明确的返回值来传递错误信息的.这与使用异常的 Java 和 Ruby ...

随机推荐

  1. vue webpack打包之后 重新修改配置文件接口API路径,无需修改代码后再打包

    用vue-cli构建的项目通常是采用前后端分离的开发模式,也就是前端与后台完全分离,此时就需要将后台接口地址打包进项目中,但是有的时候需要修改接口地址,为了避免为了修改接口地址而进行修改代码后再重新打 ...

  2. [笔记] 什么是Groovy?什么是Kotlin?

    关于Groovy 参考文章 https://www.w3cschool.cn/groovy/ 摘抄如下: Groovy是JVM的一个替代语言(替代是指可以用 Groovy 在Java平台上进行 Jav ...

  3. ROS2

    ROS2核心概念 节点 创建节点流程 编程接口初始化 创建节点并初始化 实现节点功能 销毁节点并关闭接口 #!/usr/bin/env python3 import rclpy # ROS2 Pyth ...

  4. 数据库可视化---grafana的简单使用

    简介 grafana可以连接各种数据源, 并通过给定的SQL语句做数据的定时统计和web大屏展示,也可以对外提供API进行展示, 类似这样 内含多种不同类型图表, 可以涵盖很多种监控需求, 报表可视化 ...

  5. Java调用Kettle

    Java 调用 kettle,难的不是怎么调用,而是解决 maven 依赖冲突问题,直接将 kettle 依赖,添加到我们的 maven 工程,可能会导致代码大范围报错:解决方案也很简单,就是直接从 ...

  6. fetchAll 的小小分析

    includes\database\prefetch.inc line 425 $this->defaultFetchStyle: fetch_object int 5protected $de ...

  7. VS Code 快速下载

    最近在官网下载Visual Studio Code时,下载速度特别慢,经过搜索后发现,将下载地址前部分更换为国内地址后,下载速度飞快. 具体步骤如下: VSCodeSetup-x64-1.72.0 官 ...

  8. 指针和指针运算符一起时的运算规则(比如*p++和*++p的区别)

    接下来,通过示例彻底理解自增运算符的两种用法(自减的用法与之类似,只不过是加1变成了减1). 1.++i和i++的区别 如清单1(注意代码中的注释): #include <stdio.h> ...

  9. ubuntu添加新硬盘进行分区,并挂载到/home

    ubuntu添加新硬盘,进行分区,并挂载到/home目录. 1.查看已有的磁盘,可以看到sdb还没有分区. > sudo fdisk -l 可以看到各个硬盘的设备名,一般以sda.sdb.sdc ...

  10. CTreeCtrl中通过单击获取当前选项文本

    新建了一个NM_Click消息响应函数,用hParent = m_TreeCtrl.GetSelectedItem();m_TreeCtrl.GetItemText(hParent);获取当前选中的文 ...