go defer return panic 执行顺序

news2025/1/22 17:57:55

根据代码实例运行结果来总结

说明:定义一个函数,有多个defer (用于判断多个defer执行顺序),有panic和 return (判断与defer对比执行顺序)

一、函数中有panic

package main

import "fmt"

func main() {
    fmt.Println("main func start")
    defer func(){
        fmt.Println("main defer func 1")
    }()
    s := test()
    fmt.Println("main get test() return:",s)

}

func test() (str string) {
    defer func() {
        //捕获panic
        if msg := recover(); msg != nil {
            fmt.Println("test defer func1 捕获到错误:",msg)
        }
        str = "bbb"
    }()

    defer func(){
        fmt.Println("test defer func2")
    }()

    defer func(){
        fmt.Println("test defer func3")
    }()

    str = "aaa"
    
    fmt.Println("panic抛出前")
    panic("test painc")
    fmt.Println("panic抛出后")
    
    return str
}

执行结果:

根据执行结果可知道:

  1. 函数内多个defer执行顺序是 先入后出(即入栈)

  1. panic 先于defer执行,不然defer函数内捕获不到错误

  1. panic执行后 后续逻辑及return 没有执行

二、然后将代码中 panic注释掉再执行

执行结果:

根据执行结果可知:

  1. defer中可以修改返回值,注意:前提是函数的返回值不是匿名的

三、函数返回的是匿名参数

package main

import "fmt"

func main() {
    fmt.Println("main func start")
    defer func(){
        fmt.Println("main defer func 1")
    }()
    s := test()
    fmt.Println("main get test() return:",s)

}

func test() (string) {
    str := "aaa"
    defer func() {
        //捕获panic
        if msg := recover(); msg != nil {
            fmt.Println("test defer func1 捕获到错误:",msg)
        }
        str = "ccc"
    }()

    defer func(){
        fmt.Println("test defer func2")
    }()

    defer func(){
        fmt.Println("test defer func3")
    }()

    fmt.Println("panic抛出前")
    panic("test painc")
    fmt.Println("panic抛出后")

    return str
}

执行结果:

然后注释掉panic执行结果

根据执行结果:

  1. 函数返回参数是匿名的 defer无法修改

  1. 函数中有panic 匿名的返回值是零值,因为return赋值得不到执行,defer又修改不到返回值

***注意(非常重要):这里需要提到的是函数的return是分为两个步骤:return最先执行,先将结果写入返回值中(即赋值);接着defer开始执行一些收尾工作;最后函数携带当前返回值退出(即返回值)。

有panic的时候,return第一步没有执行到,无法将结果写入返回值中,那么函数退出前则只能返回参数类型的零值

四、总结:

  1. 函数中有多个defer,则是按先进后出(压栈)执行

  1. panic先于defer执行,所以能通过defer中去捕获panic错误

  1. defer可以修改函数的返回参数,前提是函数返回的参数不是匿名的

  1. 函数执行出现panic那么return得不到执行,如果返回参数是匿名的,那么函数最终返回的是返回参数的类型零值,如果返回参数不是匿名的,在panic前有对返回参数赋值,那么就能返回这个值,如果defer有对其修改,那么返回值则是defer修改的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/151591.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【矩阵论】8. 常用矩阵总结——秩1矩阵,优阵(单位正交阵),Hermite阵

矩阵论 1. 准备知识——复数域上矩阵,Hermite变换) 1.准备知识——复数域上的内积域正交阵 1.准备知识——Hermite阵,二次型,矩阵合同,正定阵,幂0阵,幂等阵,矩阵的秩 2. 矩阵分解——SVD准备知识——奇异值…

【性能调优】【离线任务】flink处理离线任务(8000个小文件?200多亿数据量?)稳定性与性能调优探索

文章目录一、场景描述1. 任务类型描述2. 问题任务二、相关理论1.Task Slots and Resources1.1. slots与资源的隔离和共享1.2 建议cpu和slot数关系2. tm的资源配置是否合适2.1. flink load problems2.2. 阿里 flink资源配置建议三、问题分析与解决1. 测试结果比对1.1. 任务11.2.…

小程序学习(2)-----常用的各类组件

新建项目 项目->新建项目-小程序,如下图所示 新建小程序页面 只需要在 app.json->pages 中新增页面的存放路径,小程序开发者工具可帮我们自动创建对应的页面文件,如图所示: 2.常用的视图容器类组件 ① view 普通视图区域类…

Java基础算法每日5道详解(3)

136. Single Number 单号 Given a non-empty array of integers nums, every element appears twice except for one. Find that single one. You must implement a solution with a linear runtime complexity and use only constant extra space. 给定一个非空整数数组 nu…

在Multisim导入TI提供的SPICE模型

对在multisim中导入TI模型的一个记录。 multisim中只有常规的元器件,对于很多元器件multisim都没有相应的模型,这就需要手动导入了。 Multisim导入模型1、从官网下载相应的模型文件2、在Multisim中导入模型3、写在后面1、从官网下载相应的模型文件 &…

c/c++ 函数(一) setw()、isdigit()、isalpha()、atoi()、itoa()

目录 1、setw(int n) <iomanip> 2、int isdigit(char ch) <ctype.h> 3、int isalpha(int c) <ctype.h> 4、int atoi(const char* str) <stdlib.h> 5、char* itoa(int num) <stdlib.h> 1、se…

Linux 基本权限

目录 1 shell命令以及运行原理 1.1 理解 1.2 意义 2 Linux权限的概念 2.1 概念 2.2 用户分类 2.3 Linux文件属性 2.4 Linux文件权限 2.4.1 文件访问者的分类&#xff08;人&#xff09; 2.4.2 root&&普通用户 vs 拥有者&&所属组&&other 2.4…

异步架构,避免相互依赖的系统耦合

前言&#xff1a; 使用缓存架构可以减少不必要的计算&#xff0c;快速响应用户请求&#xff0c;但是缓存只能改善系统的读操作性能&#xff0c;也就是在读取数据的时候&#xff0c;可以不从数据源中读取&#xff0c;而是通过缓存读取&#xff0c;以加速数据的读取速度。 但是…

vulnhub DC系列 DC-6

总结:wpscan爆破&#xff0c;nmap提权 下载地址 DC-6.zip (Size: 619 MB)Download: http://www.five86.com/downloads/DC-6.zipDownload (Mirror): https://download.vulnhub.com/dc/DC-6.zip使用方法:解压后&#xff0c;使用vm直接打开ova文件。 漏洞分析 信息收集 这里还是使…

4. 数据处理:用R语言实现【多路替换】真高效!!

b站课程视频链接&#xff1a; https://www.bilibili.com/video/BV19x411X7C6?p1 腾讯课堂(最新&#xff0c;但是要花钱&#xff0c;我花99&#x1f622;&#x1f622;元买了&#xff0c;感觉讲的没问题&#xff0c;就是知识点结构有点乱&#xff09;&#xff1a;https://ke.qq…

Linux中的vim最小集、指令集及其配置

目录 1. vim 最小集 2 vim指令集 2.1 命令模式的指令 2.1.1 插入模式 2.1.2 移动光标 2.1.3 删除文字 2.1.4 复制 2.1.5 替换 2.1.6 撤销 2.1.7 更改 2.1.8 跳至指定的行 2.1.9 shift ~:快速大小写切换 2.2 末行模式的指令 2.2.1 set nu/set nonu 2.2.2 vs file…

【自学Python】Python变量

Python变量 Python变量教程 不论是使用哪种高级程序语言编写程序&#xff0c;变量都是其程序的基本组成单位。变量相当于内存中一个数据存储空间的表示&#xff0c;通过变量名可以访问到变量的具体的值。 Python变量 Python 是弱类型语言&#xff0c;因此 Python 变量无须声…

Hudi的核心概念 —— 时间轴(TimeLine)

文章目录时间轴&#xff08;TimeLine&#xff09;时间轴&#xff08;TimeLine&#xff09; 就是一个时间线&#xff0c;它的每一个操作都记录在内&#xff0c;每一个时刻&#xff0c;你做了什么事情&#xff0c;对某一个时刻&#xff0c;记录一个时刻的数据 Hudi 的核心是维护…

擎创运维大数据治理解决方案,荣膺金融业数字化转型突出贡献奖

近日&#xff0c;由《金融电子化》杂志社主办的“2022中国金融科技年会暨第十三届金融科技应用创新奖颁奖典礼”成功于线上举办。擎创科技“运维大数据治理解决方案”&#xff0c;荣膺“2022科技赋能金融业数字化转型突出贡献奖”。人民银行《金融科技发展规划&#xff08;2022…

C++ string类

在c语言中&#xff0c;我们想要记录字符串需要创建一个字符串的数组&#xff0c;而c则提供了另一种方式&#xff1b; 也就是这篇博客所说的string类&#xff1b; string类 #include<string> 作为字符串数组的升级版&#xff0c;string类自然也有它的独特之处——可变长数…

自动驾驶标定基础知识

目录基础概念1. 缩略语2. 为什么需要外参标定3. 基于使用场景的标定分类4. 基于方法的分类5. 基础坐标系6. 超差EOL标定1.EOL特点2. EOL标定流程3. EOL标定软件约束4. EOL标定软件流程5. 算法设计原则6. 算法基本原理背景式标定1.背景式标定的特点2. 背景式标定运行流程3. 背景…

高级树结构之线索化二叉树

文章目录一 线索化二叉树简介二 线索化规则三 前序线索化3.1 代码演示四 中序线索化4.1 代码演示五 后序线索化5.1 代码演示一 线索化二叉树简介 线索化&#xff1a;将一颗二叉树的结点指向为空的指针&#xff0c;线索化为某一种顺序遍历的的指向下一个按顺序的结点的指针一颗…

虚拟主机3种方式nginx/apache+跨域知识点整理

目录referer、prototype、array、json笔记整理: [http://t.csdn.cn/s4P8x](http://t.csdn.cn/s4P8x)虚拟主机3种方式nginx/apache跨域知识点整理一、Apache基于多IP、多端口、多域名访问1、添加网卡三种方法1、虚拟机添加网络适配器2、命令添加3、用nmtui 添加ip地址2、添加配置…

Jwt 最流行的跨域身份验证解决方案

1. 什么是JWT JSON Web Token (JWT)是一个开放标准(RFC 7519)&#xff0c;它定义了一种紧凑的、自包含的方式&#xff0c;用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任&#xff0c;因为它是数字签名的。 JWT被设计为紧凑且安全的&#xff0c;特别适用于分…

Python制做一个电脑通知小工具,再也不怕忘记事情拉~

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ Windows不是有个消息通知功能&#xff0c;挺喜欢这个功能的&#xff0c; 但是不太方便使用&#xff0c;也懒得去研究&#xff0c; 于是准备用Python自己写一个&#xff0c;通过设定通知的间隔时…