go中 panicrecoverdefer机制

 go的defer机制-CSDN博客 

常见panic场景

  • 数组或切片越界,例如 s := make([]int, 3); fmt.Println(s[5]) 会引发 panic: runtime error: index out of range
  • 空指针调用,例如 var p *Person; fmt.Println(p.Name) 会引发 panic: runtime error: invalid memory address or nil pointer dereference
  • 过早关闭 HTTP 响应体,例如 resp, err := http.Get(url); defer resp.Body.Close(); if err != nil { return err } 会引发 panic: runtime error: invalid memory address or nil pointer dereference,因为如果 http.Get 出错,resp 可能是 nil
  • 除以零,例如 x := 0; y := 1 / x 会引发 panic: runtime error: integer divide by zero
  • 向已经关闭的 channel 发送或接收消息,例如 ch := make(chan int); close(ch); ch <- 1 会引发 panic: send on closed channel
  • 重复关闭 channel,例如 ch := make(chan int); close(ch); close(ch) 会引发 panic: close of closed channel
  • 关闭未初始化的 channel,例如 var ch chan int; close(ch) 会引发 panic: close of nil channel
  • 未初始化的 map,例如 var m map[string]int; m["key"] = 1 会引发 panic: assignment to entry in nil map

recover常用的场景

  • panic 只会触发当前 Goroutine 的 defer
  • recover 只有在 defer 中调用才会生效;
package mainimport "fmt"func main() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()fmt.Println("Before panic")panic("Something went wrong")fmt.Println("After panic") // This line will not be executed
}运行结果Before panic
Recovered from panic: Something went wrong

defer,recover,panic,goroutine之间有什么联系呢

recover的作用域,recover在什么时候才会起作用

recover什么时候有效

recover未在defer内使用,是不会起任何作用

func main() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}fmt.Println("Before panic")panic("Something went wrong")fmt.Println("After panic") // This line will not be executed
}结果Before panic
panic: Something went wronggoroutine 1 [running]:
main.main()/Users/alan/GolandProjects/design-patterns/main.go:11 +0x78

recover必须搭配defer使用

recover在defer内使用才会起作用

package mainimport "fmt"func main() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()fmt.Println("Before panic")panic("Something went wrong")fmt.Println("After panic") // This line will not be executed
}运行结果Before panic
Recovered from panic: Something went wrong

recove的作用域

recover在父协程

举个例子,一般使用chan的时候都是要在发送测关闭chan,我们在接受者通过控制超时

让函数提前退出,子协程一秒钟后退出


func main() {test()time.Sleep(time.Second * 10)
}
func test() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()var ch = make(chan int)go get_data(ch)ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()defer close(ch)select {case <-ch:returncase <-ctx.Done():return}
}
func get_data(ch chan int) {time.Sleep(time.Second * 2)ch <- 1
}

结果

我们发现没有recover住panic,子协程在test方法调用退出后,发生了panic,导致整个程序panic挂掉

recover,panic同子协程

相同的例子我们,我们在引起panic的协程内进行recover,结果函数正常recover后程序正常退出

func main() {test()time.Sleep(time.Second * 10)fmt.Println("时间到了 主函数也溜了")
}
func test() {defer func() {fmt.Println("test:我先溜了")}()var ch = make(chan int)go get_data(ch)ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()defer close(ch)select {case <-ch:returncase <-ctx.Done():return}
}
func get_data(ch chan int) {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()time.Sleep(time.Second * 2)ch <- 1
}

结果

正确使用close关闭chan

recover在同级函数作用域下起效

引用

Go 语言踩坑记——panic 与 recover | 小米信息部技术团队

Go 语言 panic 和 recover 的原理 | Go 语言设计与实现

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

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

相关文章

网络通信tcp

一、udp案例 二、基于tcp: tcp //c/s tcp 客户端: 1.建立连接 socket bind connect 2.通信过程 read write close tcp服务器: 1.建立连接 socket bind listen accept 2.通信过程 read write close connect函数 int connect(int sockfd, con…

Git克隆仓库太大导致拉不下来的解决方法 fatal: fetch-pack: invalid index-pack output

一般这种问题是因为某个文件/某个文件夹/某些文件夹过大导致整个项目超过1G了导致的 试过其他教程里的设置depth为1,也改过git的postBuffer,都不管用 最后还是靠克隆指定文件夹这种方式成功把项目拉下来 1. Git Bash 输入命令 git clone --filterblob:none --sparse 项目路径…

探索Unity3D URP后处理在UI控件Image上的应用

探索Unity3D URP后处理在UI控件Image上的应用 前言初识URP配置后处理效果将后处理应用于UI控件方法一&#xff1a;自定义Shader方法二&#xff1a;RenderTexture的使用 实践操作步骤一&#xff1a;创建RenderTexture步骤二&#xff1a;UI渲染至RenderTexture步骤三&#xff1a;…

视频如何转gif?分享这几款软件!

在这个快节奏、高创意的互联网时代&#xff0c;动图&#xff08;GIF&#xff09;以其独特的魅力成为了社交媒体、聊天软件中的宠儿。它们不仅能瞬间抓住眼球&#xff0c;还能让信息传递更加生动有趣。然而&#xff0c;你是否曾为如何将精彩瞬间从视频中精准截取并转换成GIF而苦…

​北斗终端:无人驾驶领域的导航新星

一、北斗终端在无人驾驶领域的应用 北斗终端&#xff0c;作为我国自主研发的北斗卫星导航系统的重要组成部分&#xff0c;其在无人驾驶领域中的应用正逐步显现其独特魅力。北斗系统的高精度、高可靠性和良好的抗干扰性能&#xff0c;为无人驾驶车辆提供了精确的定位和导航服务…

关于超长字符串/文本对应的数据从excel导入到PL/SQL中的尝试

问题&#xff1a; 1.字符串太长 2.str绑定之的结尾null缺失 将csv文件导入到PL/SQL表中存在的一些问题 1.本来我是需要将exceL上的几十条数据导入到PL/SQL数据库的一张表中&#xff0c;结果我花了许多时间 去导入。 想想一般情况下也就几十条数据&#xff0c;直接复制粘贴就…

C语言-有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件的信息合并(按字母顺序排列),输出到一个新文件C中去-深度代码解析

&#x1f30f;个人博客&#xff1a;尹蓝锐的博客 1、题目要求 有两个磁盘文件A和B&#xff0c;各存放一行字母&#xff0c;今要求把这两个文件的信息合并&#xff08;按字母顺序排列&#xff09;&#xff0c;输出到一个新文件C中去 2、准备工作 问题1&#xff1a;为什么不需要…

chrome打印dom节点不显示节点信息

正常直接console dom节点 代码改成 var parser new DOMParser(); var docDom parser.parseFromString(testHtml, text/html); console.log(docDom) let htmlHeader ref< HTMLElement | null>(null) let htmlBoby ref< HTMLElement | null>(null) htmlHeader.v…

# 利刃出鞘_Tomcat 核心原理解析(九)-- Tomcat 安全

利刃出鞘_Tomcat 核心原理解析&#xff08;九&#xff09;-- Tomcat 安全 一、Tomcat专题 - Tomcat安全 - 配置安全 1、 删除 tomcat 的 webapps 目录下的所有文件&#xff0c;禁用 tomcat 管理界面. 如下目录均可删除&#xff1a; D:\java-test\apache-tomcat-8.5.42-wind…

深度学习入门-06

基于小土堆学习 如何把数据集和Transform结合袭来 https://pytorch.org/ 上述网址是pytorch的官网 这里会有详细的使用介绍 下述是对图像处理的专门文档 单击后可查看详细介绍 选择CIFAR10数据集 CIFAR10 数据集是一个广泛使用的计算机视觉数据集&#xff0c;包含了60000…

UV LED供电为什么要选择使用恒流驱动电源

LED为何一定要恒流供电? 在讨论此议题之前&#xff0c;什么是电源的恒流恒压&#xff1f; 什么是电源的恒流恒压   恒流&#xff0c;就是输出电流是恒定的&#xff0c;但电源电流却不是固定的&#xff0c;标称的电压只是安全上限&#xff1b;恒压&#xff0c;就是输出电压是…

力扣面试经典算法150题:跳跃游戏

跳跃游戏 今天的题目是力扣面试经典150题中的数组的中等难度题&#xff1a;跳跃游戏。 题目链接&#xff1a;https://leetcode.cn/problems/jump-game/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 给定一个非负整数数组 nums&#xff0c;你最初…

uniapp/uniapp x总结

uni-app组成和跨端原理 上图所诉 App的渲染引擎&#xff1a;同时提供了2套渲染引擎&#xff0c;.vue页面文件由webview渲染&#xff0c;原理与小程序相同&#xff1b;.nvue页面文件由原生渲染&#xff0c;原理与react native相同。开发者可以根据需要自主选择渲染引擎。 uniapp…

微信小程序uni :class不支持xxx语法

问题代码&#xff1a; <view class"cellTop"><view>{{list.payTime}}</view><view :class"payStatusClass${list.payStatus}">{{payStatusDe[list.payStatus]}}</view></view> .payStatusClass1{color: rgb(246, 122,…

鸿蒙HarmonyOS开发:创建新的Lite工程

当开始开发一个应用/服务时&#xff0c;首先需要根据工程创建向导&#xff0c;创建一个新的工程&#xff0c;工具会自动生成对应的代码和资源模板。 说明 在运行DevEco Studio工程时&#xff0c;建议每一个运行窗口有2GB以上的可用内存空间。 创建和配置新工程 DevEco Studio提…

【图文并茂】ant design pro 如何对接后端个人信息接口

上一节我们有讲到如何对接登录接口的 【图文并茂】ant design pro 如何对接登录接口 仅仅能登录是最基本的&#xff0c;但是我们要进入后台还是需要另一个接口。 这个接口有两个作用&#xff1a; 来获取当前登录账号的信息&#xff0c;比如头像&#xff0c;用户名&#xff0…

Springsecurity中的Eureka报错:Cannot execute request on any known server

完整报错信息&#xff1a; com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server 报错体现&#xff1a; 访问eureka控制面板&#xff1a; 访问测试地址&#xff1a; 控制台报错&#xff1a; 可能的报错原因&#xff…

【YOLOv8改进[Conv]】 感受野注意力卷积RFAConv(2024.3)| 使用RFAConv改进C2f + 含全部代码和详细修改方式

本文将进行在YOLOv8中使用 感受野注意力卷积RFAConv改进C2f 的实践,助力YOLOv8目标检测效果,文中含全部代码、详细修改方式。助您轻松理解改进的方法。 改进前和改进后

WEB渗透免杀篇-Golang免杀

全套完整笔记 渗透测试60w字全套md笔记&#xff1a;夸克网盘分享 往期文章 WEB渗透免杀篇-免杀工具全集-CSDN博客 WEB渗透免杀篇-加载器免杀-CSDN博客 WEB渗透免杀篇-分块免杀-CSDN博客 WEB渗透免杀篇-Powershell免杀-CSDN博客 WEB渗透免杀篇-Python源码免杀-CSDN博客 …

快手小店自动回复机器人脚本

快手小店自动回复机器人是一种利用人工智能AI技术&#xff0c;能够根据用户的会话咨询内容自动回复的工具。这种机器人可以帮助快手小店主快速、高效地回复客户消息&#xff0c;提升店铺的客户服务质量和销售效率。 甜羊浏览器是一款基于Chromium内核开发的国产浏览器&#xff…