【Hello Go】Go语言异常处理

news2024/11/15 11:24:55

Go语言异常处理

  • 异常处理
    • error接口
    • panic
    • recover
      • 延时调用错误问题

异常处理

error接口

Go语言引入了一个关于错误处理的标准模式 它是Go语言内建的接口类型 它的定义如下

type error interface {
  Error() string
}

Go语言的标准库代码包errors为用户提供了以下方法

package errors
type errorString struct {
text string
}

func New(text string) error {
return &errorString{text}
}

func (e *errorString) Error() string {
return e.text
}

另一个可以生成 error 类型值的方法是调用 fmt 包中的 Errorf 函数:

package fmt
import "errors"
func Errorf(format string, args ...interface{}) error {
return errors.New(Sprintf(format, args...))
}

下面是代码示例

import (
"errors"
"fmt"
)
func main() {
var err1 error = errors.New("a normal err1")
fmt.Println(err1) //a normal err1
var err2 error = fmt.Errorf("%s", "a normal err2")
fmt.Println(err2) //a normal err2
}

一般来说 错误处理位于函数的最后 下面是代码示例

import (
"errors"
"fmt"
)

func Divide(a, b float64) (result float64, err error) {
if b == 0 {
result = 0.0
err = errors.New("runtime error: divide by zero")
return
}
result = a / b
err = nil
return
}
func main() {
r, err := Divide(10.0, 0)
if err != nil {
fmt.Println(err) //错误处理 runtime error: divide by zero
} else {
fmt.Println(r) // 使用返回值
}
}

panic

通常情况下 我们报错时可以返回一个error值

但是如果我们遇到了不可恢复的异常 比如说数组越界访问 空指针引用等

此时就会引发panic异常


一般而言 当当panic异常发生的时候 该程序会立刻停止运行 并且立即执行在该goroutine(我们这里暂时理解为线程)下的defer的函数

随后 程序崩溃并输出日志信息 日志信息包括panic value和函数调用的堆栈跟踪信息

此外需要注意的是 并不是所有panic异常都来自运行时 我们主动调用panic函数也会引起panic异常

panic函数可以接受任何值作为参数

func panic(v interface{})

下面是代码和结果演示

package main

import "fmt"

func testA() {
	fmt.Println("testA ~~~")
}

func testB() {
	panic("panic error ~~~")
}

func testC() {
	fmt.Println("testC ~~~")
}

func main() {
	testA()
	testB()
	testC()
}

我们发现前面的函数顺序执行完毕之后到panic异常

当然如果我们自己主动写点bug比如说数组越界 除0错误 效果也是一样的

recover

程序运行时 只要引发了panic异常就会引发程序崩溃 这是我们怎么都不愿意看到的

因此Go语言给我们提供了一种专门拦截运行时异常的内建函数 – recover

它可以使程序从panic状态恢复并获得流程控制权

注意:!!! recover只有在defer调用的函数中有效

如果说调用了内置函数decover并且定义该defer语句的函数发生了panic异常 recover会从panic中恢复 并且返回panic和vlaue 导致panic异常的函数不会正常运行 但会正常返回

但是在未发生panic时调用recover recover会返回nil

代码演示如下

package main

import "fmt"

func testA() {
	fmt.Println("testA ~~~")
}

func testB() (err error) {

	defer func() {
		if x := recover(); x != nil {
			// 此时panic和value被添加到x中
			err = fmt.Errorf("internal error: %v", x)
		}
	}()
	panic("panic error ~~~")

	return err
}

func testC() {
	fmt.Println("testC ~~~")
}

func main() {
	testA()
	err := testB()
	fmt.Println(err)
	testC()
}

我们依旧是在test2中主动调用了panic异常

只不过我们在前面延时调用了一个匿名函数

	defer func() {
		if x := recover(); x != nil {
			// 此时panic和value被添加到x中
			err = fmt.Errorf("internal error: %v", x)
		}
	}()

在这个匿名函数中我们调用了recover函数 并且接受了err

最终我们可以发现我们的程序正常运行下去了

在这里插入图片描述

延时调用错误问题

如果我们在延时调用中也引发了panic异常 那么该panic异常可以被后续延时调用的recover捕获

代码和结果演示如下

func test() {
	defer func() {
		fmt.Println(recover())
	}()

	defer func() {
		panic("test2")
	}()

	panic("test1")
}

func main() {
	test()
}

此时我们的recover捕获的错误就不是test1 而是 test2

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

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

相关文章

react之基于@reduxjs/toolkit使用react-redux

react之基于reduxjs/toolkit使用react-redux 一、配置基础环境二、使用React Toolkit 创建 counterStore三、为React注入store四、React组件使用store中的数据五、实现效果六、提交action传递参数七、异步状态操作 一、配置基础环境 1.使用cra快速创建一个react项目 npx crea…

前端面试:如何实现并发请求数量控制?

题目:实现一个并发请求函数concurrencyRequest(urls, maxNum) 要求如下: 要求最大并发数 maxNum;每当有一个请求返回,就留下一个空位,可以增加新的请求;所有请求完成后,结果按照 urls 里面的顺序依次打出;…

2024年全网最全的Jmeter+ant+jenkins实现持续集成教程

jmeterantjenkins持续集成 一、下载并配置jmeter 首先下载jmeter工具,并配置好环境变量;参考:https://www.cnblogs.com/YouJeffrey/p/16029894.html jmeter默认保存的是.jtl格式的文件,要设置一下bin/jmeter.properties,文件内容…

警惕.360勒索病毒,您需要知道的预防和恢复方法。

引言: 网络威胁的演变无常,.360勒索病毒作为一种新兴的勒索软件,以其狡猾性备受关注。本文将深入介绍.360勒索病毒的特点,提供解决方案以恢复被其加密的数据,并分享一系列强化网络安全的预防措施。如果您在面对被勒索…

自动驾驶学习笔记(十)——Cyber通信

#Apollo开发者# 学习课程的传送门如下,当您也准备学习自动驾驶时,可以和我一同前往: 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo Beta宣讲和线下沙龙》免费报名—>传送门 文章目录 前言 Cyber通信 编写代码 编译程序 运行…

概念解析 | 网络安全数字孪生(Digital Twin of Cyber Security, DTCS)技术

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:网络安全数字孪生。 概念解析 | 网络安全的“数字镜像” —— 网络安全数字孪生 1. 背景介绍 随着数字化转型进程的深入推进,网络空间安全问题日益凸显。当前的网络安全防护面…

RTD系统

RTD(实时派工系统)帮助半导体工厂优化派工,提升生产效率,提高设备利用率,降低Lot Cycle Time,RTD分为:WhatNext和WhereNext,解决工厂内部机台下一步跑什么Lot和Lot生产完后去哪里的问…

人类智能的精髓超出了统计概率

处理不确定性好坏的程度是衡量各种智能系统高低的一个重要指标。在处理不确定性时,智能系统需要具备推理、学习和决策的能力,通常使用概率和统计等方法来建模和处理不确定性,以便更好地应对现实世界中的复杂问题。统计概率是基于大量观察和数…

可拖动、可靠边的 popupWindow 实现

0 背景 开发要实现一个可以拖动的圆角小窗&#xff0c;要求松手时&#xff0c;哪边近些靠哪边。并且还规定了拖动范围。样式如下&#xff1a; 1 实现 首先把 PopupWindow 的布局文件 pop.xml 实现 <?xml version"1.0" encoding"utf-8"?> <R…

变周期控制思路

举例&#xff1a;热值调节的过程中&#xff0c;调节周期在偏差较小时&#xff0c;可以设置较大些&#xff0c;调节周期在偏差较大时&#xff0c;可以设置较小些。并且在偏差较大时&#xff0c;立刻进入调节&#xff08;计时器清零&#xff09;。 -350<偏差<600&#xff0…

Windows安装Vmware 虚拟机

目录 一、Vmware 虚拟机介绍 二、Vmware 虚拟机的三种网络模式 2.1桥接模式 2.2仅主机模式 2.3NAT 网络地址转换模式 三、Vmware 虚拟机的安装 一、Vmware 虚拟机介绍 VMware Workstation Pro 是一款可以在个人电脑的操作系统上创建一个完全与主机操作系统隔离的 虚拟机&…

星火模型(Spark)的langchain 实现

星火模型的langchain实现 测试已通过&#xff0c;希望有所帮助。 使用前请先安装环境&#xff1a; pip install githttps://github.com/shell-nlp/spark-ai-python.git注意&#xff1a; 一定要使用上面方式安装spark库&#xff0c;因对官方的库做了改动。官方的库已经长时间不…

十、Linux运行级别

1.基本介绍 运行级别说明&#xff1a; 0&#xff1a;关机 1&#xff1a;单用户【找回丢失密码】 2&#xff1a;多用户状态没有网络服务 【非常少】 3&#xff1a;多用户状态有网络服务 【最多】 4&#xff1a;系统未使用保留给用户 5&#xff1a;图形界面【Linux一启动自动进入…

【Java集合】聊聊Hashmap的哈希函数、扩容、树化

哈希函数 hashmap是开发中常用的一个集合&#xff0c;除了一些基本的属性、put、get等流程&#xff0c;本篇文章主要介绍下哈希函数、扩容、树化的一些细节。 而hash函数就是hashmap的重中之重。 static final int hash(Object key) {int h;return (key null) ? 0 : (h key…

AVL树实现

目录 ​编辑 一&#xff0c;AVL树的概念 二&#xff0c;实现AVL树&#xff08;部分&#xff09; 1.AVL树的节点 2.AVL数的插入 1.当根节点为nullptr时要执行如下代码&#xff1a; 2.当根节点不为nullptr时 1.当parent的_bf变为0时&#xff0c;parent之前的_bf的大小就是…

使用持久卷部署 WordPress 和 MySQL

&#x1f5d3;️实验环境 OS名称Microsoft Windows 11 家庭中文版系统类型x64-based PCDocker版本Docker version 24.0.6, build ed223bcminikube版本v1.32.0 &#x1f587;️创建 kustomization.yaml 你可以通过 kustomization.yaml 中的生成器创建一个 Secret存储密码或密…

2024年csdn最新最全的web自动化测试思路及实战

Page Objects 设计模式 Page Objects概念&#xff1a; Page Objects是指UI界面上用于与用户进行交互的对象 pageobjects 设计模式概念&#xff1a; pageobjects 模式是Selenium中的一种测试设计模式&#xff0c;主要是将每一个页面设计为一个Class&#xff0c;其中包含页面中…

滑动窗口练习(一)— 固定窗口最大值问题

题目 假设一个固定大小为W的窗口&#xff0c;依次划过arr&#xff0c; 返回每一次滑出状况的最大值 例如&#xff0c;arr [4,3,5,4,3,3,6,7], W 3 返回&#xff1a;[5,5,5,4,6,7] 暴力对数器 暴力对数器方法主要是用来做校验&#xff0c;不在乎时间复杂度&#xff0c;逻辑上…

95. 最长公共子序列

题目 题解 class Solution:def longestCommonSubsequence(self, text1: str, text2: str) -> int:# 定义状态&#xff1a;dp[i][j]表示s1[0:i]和s2[0:j]的最长公共子序列dp [[0 for j in range(len(text2)1)] for i in range(len(text1) 1)]# badcase: dp[i][0] 0, dp[0…

[C/C++]数据结构 LeetCode:用栈实现队列

题目描述: 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元素int peek() 返…