go错误处理——return,panic,defer

Go语言panic与recover机制详解:调用栈可视化与错误处理实践 在Go语言中,错误处理机制是构建健壮应用程序的核心。与传统的try-catch异常模型不同,Go采用显式错误返回值与panic/recover组合机制。panic代表程序运行时遇到的致命错误,它会立即中断当前函数执行,并开始沿函数调用栈向上回溯,依次执行各层函数的defer延迟调用。recover作为内置函数,只能在defer中调用,用于捕获并中止panic的传播过程,但关键点在于它并不能让发生panic的函数继续执行后续代码,而是让程序控制流返回到recover所在函数的上一层调用者。理解这一动态传播机制 阅读详情

return和defer的顺序:

return先返回,再运行defer,可以修改返回值:

package main

import (
    "fmt"
)

func main() {
    fmt.Println(test())
}
//返回值为2
func test() (result int) {
    defer func() {
        result++
    }()
    return 1 //return函数先返回 result被赋值为1 然后再result++
}

这里有个比较好玩儿的点,因为返回值是具名的,所以我们return 1是对result赋值为1了。

另外如果是不具名的返回值,但是你return了一个具名的变量,是否会对返回值产生修改作用。

package main

import (
    "fmt"
)

func main() {
    fmt.Println(test())
}
//输出为0
func test() int {
    var a int
    defer func() {
        a++
    }()
    return a 
}

证明不能对返回值进行修改了,具体跟作用域应该有关系,有时间再深究。当然如果将a返回给具名的返回值result然后修改result当然能修改返回值。

项目中遇到过的使用

在对panic的处理中,将panic的错误信息作为返回值,简化版代码如下:

package main

import (
    "fmt"
    "runtime/debug"
)

func main() {
    fmt.Println(test())
}
func test() (err error) {
    defer func() {
        if e := recover(); e != nil {
            err = fmt.Errorf("%s \n panic:\n %s", e, debug.Stack())
            //打印e(panic的异常信息补货结果),并且强烈推荐打印堆栈信息用来定位错误。
        }
    }()
    var a int
    a = 1 / a
    return nil
}

返回结果如下:

runtime error: integer divide by zero 
 panic:
 goroutine 1 [running]:
runtime/debug.Stack(0xc042031d88, 0x49d220, 0xc042004060)
    C:/Go/src/runtime/debug/stack.go:24 +0x80
main.test.func1(0xc042031ea8)
    C:/Users/colinhome/Documents/GitHub/test/src/structindex/base64.go:14 +0x6a
panic(0x49d220, 0xc042004060)
    C:/Go/src/runtime/panic.go:458 +0x251
main.test(0x0, 0x0)
    C:/Users/colinhome/Documents/GitHub/test/src/structindex/base64.go:19 +0x80
main.main()
    C:/Users/colinhome/Documents/GitHub/test/src/structindex/base64.go:9 +0x3b

能定位到具体行数。方便调试。

Go错误处理:error、panic、recover的正确姿势 实际项目里光用errors.New不够,你需要自定义错误类型,携带更多的上下文信息。import ("errors""fmt"// ValidationError 自定义错误类型// 实现了error接口的Error()方法Field string // 出错的字段名Message string // 错误描述return fmt.Sprintf("字段[%s]校验失败 %s", e.Field, e.Message)// NotFoundError 资源不存在错误。 阅读详情

相关推荐

Golang defer的执行时机:你必须知道的细节

本文聚焦Golang中defer语句的执行时机defer何时被注册?何时被执行?多个defer的执行顺序如何?defer与return语句的执行先后关系?函数发生panic时,defer还会执行吗?闭包defer的变量捕获陷阱。本文从生活故事引入,用“餐厅用餐”类比defer的行为;通过核心概念解释、代码示例、流程图,逐步拆解执行时机;最后结合实战案例和常见问题,帮你彻底掌握细节。defer注册的函数会在当前函数返回前执行(包括正常返回和return语句触发的返回)。

AI Agent Harness Engineering 673

go: panic与recover

panic是go语言在运行时发生的错误,如数组访问越界、空指针引用等,这些运行时错误会引起程序崩溃。这并不是我们想看到的,程序崩溃可能造成体验停止、服务中断,就像没有人希望在马桶冲水冲到一半时坏掉。 什么是panic? 传统上一般用error来控制go语言中遇到的错误。Errors能满足我们大部分时候的开发需求 但有情况下,程序在发生异常后无法继续运行下去,这时我们用panic终止程序。 当一个...

Enzo 478

AutoCAD 2024 Mac版安装激活教程:从下载到破解一站式解决方案

本文提供AutoCAD 2024 Mac版的详细安装与优化指南,包括系统要求检查、下载安装流程、常见问题解决方案及性能优化设置。特别介绍了如何应用最新补丁和Update保持软件性能,帮助用户顺利完成从安装到破解的全过程。

weixin_29239661的博客 833

GO语言中defer和return的错误认识以及纠正

func1() (i int)//这里的最后一个括号(i int)指明了返回的参数个数、类型以及返回值的变量名(该变量名可在函数中修改)

m0_57053955的博客 291

告别配置噩梦:用Vcpkg三行命令为Easy3D自动安装Boost、CGAL和Qt(VS2022实测)

本文详细介绍了如何使用Vcpkg工具在VS2022环境下为Easy3D项目一键安装Boost、CGAL和Qt等依赖库,解决传统手动配置的复杂性问题。通过三行简单命令即可自动完成下载、编译和路径配置,大幅提升开发效率,特别适合C++开发者快速搭建3D图形开发环境。

weixin_42525582的博客 209

Delta并联机械手-Codesys实现以及正解逆解研究

由于Codesys的Robotics模块有Delta并联机械手的运动模型,因此借助Codesys的机械手运动模型,研究自己的正解逆解算法。

weixin_42386991的博客 5561

go语言基础5——日志log

无论是软件开发的调试阶段还是软件上线之后的运行阶段,日志一直都是非常重要的一个环节,我们也应该养成在程序中记录日志的好习惯。 log Go语言内置的log包实现了简单的日志服务。本文介绍了标准库log的基本使用。 使用Logger log包定义了Logger类型,该类型提供了一些格式化输出的方法。本包也提供了一个预定义的“标准”logger,可以通过调用函数Print系列(Print|Printf|Println)、Fatal系列(Fatal|Fatalf|Fatalln)、和Panic系列(Pan

一蓑烟雨任平生 1455

RK3588交叉编译实战:从环境搭建到程序部署

本文详细介绍了在X86主机上为RK3588开发板搭建交叉编译环境的完整流程。从获取ARM工具链、配置sysroot,到实战编译Hello World和Qt应用程序,并提供了部署方法和常见问题解决方案。通过交叉编译,开发者可以在高性能PC上高效开发,并在ARM架构的RK3588上运行程序,大幅提升嵌入式开发效率。

weixin_29191669的博客 274

golang日志库使用与对比

1、log简介 golang内置了log包,实现简单的日志服务。通过调用log包的函数,可以实现简单的日志打印功能。2、log使用 log包中有3个系列的日志打印函数,分别print系列、panic系列、fatal系列。函数系列 作用 print 单纯打印日志 panic 打印日志,抛出panic异常 fatal 打印日志,强制结束程序(os.Exit(1)),defer函数不会执行 2.1 简单示例 func main() { defer fmt.Println(“panic退出前处理”) log.Pri

S_ZaiJiangHu的博客 6951

指纹对抗指南:如何绕过Cloudflare与Akamai的5s盾与浏览器指纹检测

现在的CDN反爬技术虽然越来越强,但是道高一尺魔高一丈,只要掌握了指纹伪造、流量伪装、行为模拟这些核心技术,就可以绕过绝大多数的防护措施。对抗过程中要注意效率和成本的平衡,小规模爬取用Playwright+stealth最方便,大规模爬取用curl_cffi+代理池性价比最高,遇到验证码用打码平台或者自动识别服务,不需要死磕破解。本文介绍的方案已经在实战中验证过,可以绕过95%以上的Cloudflare/Akamai防护,成功率非常高。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 295

【项目实战】Java9的新特性模块化(Module)

Java 9引入了模块化系统,称为"Java Platform Module System"(JPMS)这个系统允许将Java程序分成模块,每个模块都有自己的规范,可以明确地声明它依赖于哪些其他模块,并且只能访问被其所依赖的模块暴露的API。这样可以模块化就是增加了更高级别的聚合,是Package的封装体。Package是一些类路径名字的约定,而模块是一个或多个Package组成的封装体。

奶爸的编程之路,也就一周冷个三天 1896

Golang panic,defer,return 的返回

Golang返回过程-return,defer,panic 首先有以下几个原则:  函数返回return是函数的返回标志,并不是真正的返回,不代表执行结束一个函数最多只会panic一次defer按先进后出的形式执行,defer在return之后执行 return 和 defer 一个有返回值的函数,可以有2中表示 func sum1(x,y int)int{ s :

qq_33558437的博客 2150

使用STM32制作智能窗帘控制

以上就是一个简单的基于STM32的智能窗帘控制代码案例。通过感知光线强度和控制步进电机的旋转,我们可以实现智能窗帘的自动开启和关闭。通过定时器的中断来控制步进电机的旋转,从而实现窗帘的开启和关闭动作。最后,我们需要实现主函数和中断函数。在主函数中,我们需要初始化硬件资源,然后进入一个无限循环来不断检测光敏电阻的值,并根据其值来控制窗帘的开启和关闭。接下来,我们需要编写功能函数,用于控制窗帘的开启和关闭。然后,我们需要配置STM32开发环境,并创建一个新的工程。接下来,我们初始化相关的硬件资源。

2401_85258012的博客 276

golang panic recover return defer的逻辑顺序问题

package main import "fmt" //验证golang return defer recover 之间的顺序关系 func main() { defer func() { //捕获panic fmt.Println("00000000") if r := recover(); r != nil { fmt.Println(r) } }() fmt.Println("let's go !!!") test1() test2() fmt.Println(

qq_15115793的博客 1931

基于SiamFC的红外目标跟踪

初始化阶段:在第一帧中,通过用户标注获得目标框,从目标区域中提取一个固定大小的模板(称为 exemplar)。搜索阶段:在后续帧中,在以当前目标中心为中心的较大区域(称为 instance)内进行搜索,将模板与搜索区域通过卷积操作得到响应图。位置更新:在响应图中找到峰值位置,并转换到原图坐标,用以更新目标中心。部分实现中还会考虑多尺度搜索和目标尺寸更新。import cv2# 定义 SiamFC 简易网络(示例)# 特征提取部分,注意红外图像通常为单通道,使用较少的卷积核数提高实时性。

weixin_43745234的博客 774

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

golang panic的错误回收和简单的使用场景

golang panic的错误回收和简单的使用场景 代码示例 package main import( "fmt" ) func main(){ _,err:=deferPanic(8,0) if err!=nil{ fmt.Println(err) } fmt.Println("这里还是会执行的") } //panic ...

weixin_30432579的博客 370

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

《Go语言学习笔记》 - 第四章 - 延迟调用

5. 延迟调用 语句defer用来延迟一个方法或者函数的执行。被延迟的方法或者函数直到当前函数执行结束前才会被执行,因此,defer常用于资源释放、解除锁定、错误处理等操作。 5.1 defer的几个注意点 被defer的函数只是延迟了调用的时间,但是函数参数的传递是在代码执行到函数所在的那一行时发生的,如果函数传入的参数是一个函数,那么会立即执行。 func main(){ x,y := ...

来自东印度的人 313

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Go语言中defer语句使用小结

Go语言中defer语句使用小结 defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开socket连接、解锁一个加锁的资源。Go语言机制担保一定会执行defer语句中的代码。其它语言中也有类似的机制,比如Java、C#语言里的finally语句,C++语言里的析构函数(Destructor)可以起类似的作用,C++语言机制担保在对象被销毁前一定会执行析构函数中的代码。C++中的析构函数析构的是对象,Go中的defer析构的是函数。 文章目录G

weixin_50071922的博客 448

Go语言中的错误处理

Golang/Go语言中的资源管理和出错处理,defer、panic、recover

whhcs的博客 1128

为什么90%的Go开发者答不好defer面试题?这7种场景你必须掌握

掌握defer核心场景,破解Go面试难题。本文深入解析Go后端开发者1024面试高频题解析中的defer机制,涵盖函数返回、循环、闭包等7大典型应用,揭示执行顺序与底层原理,助你精准应对面试陷阱,值得收藏。

CompiTide的博客 778

go mysql recover_golang recover后怎么返回

golang recover后怎么返回,函数,机制,都会,在这个,还可以golang recover后怎么返回易采站长站,站长之家为您整理了golang recover后怎么返回的相关内容。recover虽然没有try catch机制,Go其实有一种类似的recover机制,功能弱了点,用法很简单: (推荐学习:go)package mainimpor...

weixin_33772442的博客 641

Go语言的defer栈与执行顺序在资源清理与错误处理中的确定性

Go语言中的defer机制以其独特的执行顺序和确定性,成为资源清理与错误处理的利器。通过将函数调用压入defer栈,Go确保了在函数返回前这些操作能够按照后进先出的顺序执行。不同于其他语言的析构机制,Go的defer提供了完全确定的执行时机。当函数因错误提前返回时,已注册的defer函数仍会确保执行,避免了传统try-catch-finally模式中的代码重复。defer栈的核心特性是后进先出(LIFO)的执行顺序。当多个defer语句出现在同一函数中时,最后一个被注册的defer函数会最先执行。

niaydm_924的博客 192

Go语言控制流语句

本篇文章深入讲解Go语言的流程控制语句,包括条件判断、循环、跳转和选择结构。掌握这些语句是编写逻辑复杂程序的基础。

星航夜空的帆舟 227

【Go语言-Day 18】从入门到精通:defer、return 与 panic 的执行顺序全解析

本文深入探讨了 Go 语言中一个极具特色且功能强大的关键字——`defer`。`defer` 语句能够将其后的函数调用延迟到当前函数执行完毕前再执行,极大地简化了资源管理(如文件关闭、锁的释放)和错误处理流程。文章将从 `defer` 的基本用法入手,详细解析其核心的 **“后进先出”(LIFO)** 执行顺序,并通过文件操作、互斥锁等实战场景展示其应用价值。

吴师兄大模型的博客 603

Golang 之 defer,panic 和 recover 的用法

一、defer 概念 在 golang 中,defer 代码块会在函数调用链表中增加一个函数调用,是在函数正常返回(也就是 return)之后添加的一个函数调用。因此,defer 通常用于释放函数内部变量 存在隐患的示例 // 实现文件的复制 func CopyFile(dstName, srcName string) (written int64, err error) { src, err := os.Open(srcName) if err != nil { return }

shenxinde的博客 1383
下一篇: 实习日常(1)——提高代码质量:过度保护以及TDD,BDD
V_code
博客等级 码龄12年 5粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值