脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Golang - Golang中错误处理机制详解

Golang中错误处理机制详解

2024-05-07 16:102021dragon Golang

平时在项目开发过程中少不了对错误的处理,一个好用的系统首先要确保其健壮性,不能经常发生错误就卡死之类的情况,为了让我们的程序更加健壮,我们就需要知道golang里的错误处理机制是怎么样的,这篇文章带大家一起学习,需要的

Golang错误处理机制

panic异常

panic异常

  • Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,比如除零错误、数组访问越界、空指针引用等,这些运行时错误会引起panic异常。
  • 当panic异常发生时,程序会中断运行,并立即执行当前函数中的defer语句,然后程序会从调用栈中逐级返回,返回同时执行各级函数中的defer语句,直到panic被捕获或程序终止。

例如,下面的代码在运行过程中,由于存在除零错误将导致panic异常。如下:

package main

import "fmt"

func Division(num1 int, num2 int) int {
	defer fmt.Println("Division defer...")
	return num1 / num2
}

func main() {
	defer fmt.Println("main defer...")
	// panic异常
	result := Division(10, 0)
	fmt.Printf("result = %d\n", result)
	fmt.Println("other code...")
}

运行代码后可以看到,main函数中调用Division函数之后的代码没有被执行。但在程序退出之前,Division和main函数中的defer语句被逐一执行。如下:

Golang中错误处理机制详解

recover捕获异常

recover捕获异常

  • 当触发panic异常时,我们希望程序可以继续运行,并希望在触发异常后,能够执行某些操作,比如给管理员发送一条告警信息。
  • 在Go中,捕获异常通过在defer中调用内建函数recover实现,recover函数会使程序从panic中恢复,并返回触发panic的值,如果程序没有发生panic,则recover调用将会返回nil。
  • 需要注意的是,当异常被捕获后,触发panic异常的函数也不会继续运行,但能正常返回。

例如,下面在Division函数的defer中捕获了panic异常,并将触发panic异常的值进行了返回。如下:

package main

import "fmt"

func Division(num1 int, num2 int) (result int, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = r.(error) // 类型断言,将r转换为error类型(后续介绍)
		}
	}()
	return num1 / num2, nil
}

func main() {
	// recover捕获异常
	result, err := Division(10, 0)
	if err != nil {
		fmt.Printf("division operation error, err = %v\n", err)
	} else {
		fmt.Printf("result = %d\n", result)
	}
}

运行代码后可以看到,由于panic异常被捕获使得Division函数正常返回,同时main函数后续的代码也被正常执行。如下:

Golang中错误处理机制详解

由于panic异常会逐级抛出,直到异常被捕获或程序终止,因此可以选择在调用链的任意一个函数中对panic进行捕获。如下:

package main

import "fmt"

func Division(num1 int, num2 int) int {
	return num1 / num2
}

func main() {
	// recover捕获异常
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("recoverd from panic, err = %v\n", err)
		}
	}()
	result := Division(10, 0)
	fmt.Printf("result = %d\n", result)
	fmt.Println("other code...")
}

由于Division函数中没有对panic进行捕获,导致main函数触发panic异常,虽然在main函数中对panic进行了捕获,但main函数的后续代码将不会被执行。如下:

Golang中错误处理机制详解

自定义错误

自定义错误

  • 不是只有程序在运行时出现错误才能触发panic异常,通过调用内建函数panic也能触发panic异常。
  • panic函数能够接收任何类型的值作为参数,并在触发panic时将其作为触发panic的值。
  • 触发panic的值通常是error类型的,通过errors包中的New函数可以创建一个error类型的错误值,该函数接收一个string类型的参数,并返回创建的error类型的错误值。

例如,我们规定除数不能为20,否则触发panic异常。如下:

package main

import (
	"errors"
	"fmt"
)

func Division(num1 int, num2 int) (result int, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = r.(error)
		}
	}()
	if num2 == 20 {
		panic(errors.New("integer divide by 20"))
	}
	return num1 / num2, nil
}

func main() {
	// recover捕获异常
	result, err := Division(10, 20)
	if err != nil {
		fmt.Printf("division operation error, err = %v\n", err)
	} else {
		fmt.Printf("result = %d\n", result)
	}
}

运行代码后可以看到,通过panic函数触发的异常也能够成功被捕获。如下:

Golang中错误处理机制详解

说明一下: 通过recover将panic捕获后,可以继续通过调用panic函数将panic再次抛出,使其传播到更高层的调用栈进行进一步处理,这叫做异常的重新抛出。

到此这篇关于Golang中错误处理机制详解的文章就介绍到这了,更多相关Golang错误处理机制内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/chenlong_cxy/article/details/138130393

延伸 · 阅读

精彩推荐
  • GolangGolang Redis:构建高效和可扩展的应用程序

    Golang Redis:构建高效和可扩展的应用程序

    在这份完整的指南中,我们将了解什么是Redis,学习使用Docker Compose安装Redis的简便过程,并掌握将Redis与Golang集成的艺术。...

    技术的游戏6242024-03-01
  • GolangGo语言的变量定义详情

    Go语言的变量定义详情

    这篇文章主要介绍了Go语言的变量定义详情,go定义变量的方式和c,c++,java语法不一样,var 变量名类型,var在前,变量名在中间,类型在后面,下文更多详细内容需...

    苏州程序大白4812022-09-12
  • Golanggolang time包的用法详解

    golang time包的用法详解

    这篇文章主要介绍了golang time包的用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着...

    飘ing4612020-05-24
  • GolangGolang多线程刷票的实现代码

    Golang多线程刷票的实现代码

    这篇文章主要介绍了Golang多线程刷票的相关资料,这里实现刷票的功能,对于投票,刷票的很方便,并附实现代码,需要的朋友可以参考下 ...

    lqh2932020-05-08
  • Golanggolang 使用time包获取时间戳与日期格式化操作

    golang 使用time包获取时间戳与日期格式化操作

    这篇文章主要介绍了golang 使用time包获取时间戳与日期格式化操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    Wang123.net18992021-03-01
  • GolangGO 实现高并发高可用分布式系统:Log微服务的实现

    GO 实现高并发高可用分布式系统:Log微服务的实现

    在大数据时代,具备高并发,高可用,理解微服务系统设计的人员需求很大,如果你想从事后台开发,在JD的描述中最常见的要求就是有所谓的“高并发”...

    Coding迪斯尼4752022-01-10
  • GolangGo 第三方库之类型转换问题

    Go 第三方库之类型转换问题

    今天给大家介绍一个第三方库,专门处理类型转换的问题。对Go 第三方库之类型转换问题感兴趣的朋友跟随小编一起看看吧...

    polarisxu6612021-09-17
  • Golanggo Http Post 发送文件流案例

    go Http Post 发送文件流案例

    这篇文章主要介绍了go Http Post 发送文件流案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    中国流浪猫19102021-03-07