go语言中使用defer、panic、recover处理异常

go语言中的异常处理,没有try...catch等,而是使用defer、panic、recover来处理异常。

1、首先,panic 是用来表示非常严重的不可恢复的错误的。在Go语言中这是一个内置函数,如果在程序中遇到异常,或者调用panic函数,程序会立即退出(除非recover)。如下代码:

package main

import "fmt"

func main() {
	a := 10
	b := 0
	c := a / b

	fmt.Println(c)
}

  程序的输出如下:

?  demo06 go run main.go
panic: runtime error: integer divide by zero

goroutine 1 [running]:
main.main()
        /Users/qstudy/myfiles/project/src/go_dev/day11/demo06/main.go:8 +0x11
exit status 2

  在这个输出中,我们可以看到有个panic。

2、defer能保证在函数结束最后执行该方法(有问题的或者引发panic的函数),但是有个条件:必须在错误出错之前进行拦截,在错误出现后进行错误捕获,如果在定义的方法中defer定义的方法如果在panic后面,defer定义的方法就无法执行到。如下代码:

package main

import "fmt"

func test(i int) {
	var arr [10]int
	// 错误拦截必须配合defer使用,通过匿名函数使用,在错误之前引用
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println(err)
		}
	}()

	arr[i] = 123
	fmt.Println(arr)
}

func main() {
	i := 10
	test(i)
	fmt.Println("hello world")
}

  执行后输出如下:

runtime error: index out of range
hello world

  从以上结果可以看出,如果panic被recover捕获接收到,panic后的方法还是能继续执行的。

来自一本书书上面的总结:

“当在一个函数执行过程中调用panic()函数时,正常的函数执行流程将立即终止,但函数中
之前使用defer 关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致
逐层向上执行panic流程,直至所属的goroutine 中所有正在执行的函数被终止。错误信息将被报
告,包括在调用panic()函数时传入的参数,这个过程称为错误处理流程。”

原文地址:https://www.cnblogs.com/qstudy/p/10493254.html

时间: 2024-08-04 02:09:08

go语言中使用defer、panic、recover处理异常的相关文章

Go语言中异常处理painc()和recover()的用法

Go语言中异常处理painc()和recover()的用法 1.Painc用法是:用于抛出错误.Recover()用法是:将Recover()写在defer中,并且在可能发生panic的地方之前,先调用此defer的东西(让系统方法域结束时,有代码要执行.)当程序遇到panic的时候(当然,也可以正常的调用出现的异常情况),系统将跳过后面的代码,进入defer,如果defer函数中recover(),则返回捕获到的panic的值. 2.代码: package main import "fmt&q

defer, panic, recover使用总结

1. defer : 延迟调用.多个defer,依次入栈,在函数即将退出时,依次出栈调用 1 package main 2 import "fmt" 3 func main() { 4 defer func() { 5 fmt.Println("defer one") 6 }() 7 defer func() { 8 fmt.Println("defer two") 9 }() 10 defer func() { 11 fmt.Println(&

Go 语言中的 Array,Slice,Map 和 Set

转自:https://se77en.cc/ Array(数组) 内部机制 在 Go 语言中数组是固定长度的数据类型,它包含相同类型的连续的元素,这些元素可以是内建类型,像数字和字符串,也可以是结构类型,元素可以通过唯一的索引值访问,从 0 开始. 数组是很有价值的数据结构,因为它的内存分配是连续的,内存连续意味着可是让它在 CPU 缓存中待更久,所以迭代数组和移动元素都会非常迅速. 数组声明和初始化 通过指定数据类型和元素个数(数组长度)来声明数组. // 声明一个长度为5的整数数组 var a

Go语言中使用MySql数据库

Go语言中使用MySql数据库 1.MySQL驱动 Go中支持MySQL的驱动目前比较多,有如下几种,有些是支持database/sql标准,而有些是采用了自己的实现接口,常用的有如下几种: https://github.com/Go-SQL-Driver/MySQL 支持database/sql,全部采用go写. https://github.com/ziutek/mymysql 支持database/sql,也支持自定义的接口,全部采用go写. https://github.com/Phil

Go语言中使用SQLite数据库

Go语言中使用SQLite数据库 1.驱动 Go支持sqlite的驱动也比较多,但是好多都是不支持database/sql接口的 https://github.com/mattn/go-sqlite3 支持database/sql接口,基于cgo(关于cgo的知识请参看官方文档或者本书后面的章节)写的 https://github.com/feyeleanor/gosqlite3 不支持database/sql接口,基于cgo写的 https://github.com/phf/go-sqlite

在Go语言中记录log:seelog包

前两周调bug调的吐血,虽然解决了但是还是挺浪费时间的.跟同事聊了聊,觉得我们现在项目中的日志记录太少了,导致出了问题不知道怎么下手,还得自己改代码记录日志,然后排查问题.这样如果将来还有bug的话还得这么调,很麻烦,让我深入看一下go语言中如何记录日志(好吧我最近就跟日志耗上了). 根据python的经验和目前项目中的要求,我对日志的要求有两个: 一是定义日志级别,可以记录debug/warning/error之类的不同级别的日志,这样的话,在通常正常运行的时候,就只需要记录一下运行状态,而报

Go语言中查询SqlServer数据库

一.Go语言中查询MsSQL数据库: // main.go package main import ( "database/sql" "fmt" "log" "time" _ "github.com/denisenkom/go-mssqldb" ) func main() { var isdebug = true var server = "localhost" var port = 1

在 go/golang语言中使用 google Protocol Buffer

怎么在go语言中实用google protocol Buffer呢? 现在的潮流趋势就是一键搞定,跟ubuntu安装软件一样 go get code.google.com/p/goprotobuf/{proto,protoc-gen-go} go install  code.google.com/p/goprotobuf/proto 搞定,可以在 $GO_PATH/bin下找到 protoc-gen-go 这个程序,那么就可以实用protoc-gen-go 进行go语言的proto文件的自动生成

Go语言中时间函数及定时器的使用

Go语言中时间函数及定时器.休眠等功能的实现和使用,代码如下,有需要的小伙伴直接拿去 package main import ( "time" "fmt" ) func main() { // 设置时区,如果name是""或"UTC",返回UTC: // 如果name是"Local",返回Local: // 否则name应该是IANA时区数据库里有记录的地点名(该数据库记录了地点和对应的时区),如"