go-随笔(一)

error

go语言和其他主流语言比较,被谈及最多的内容可能就是繁琐的错误处理

刚开始的时候觉得每次都要接收错误很麻烦,写多了习惯了就会感觉还行,可以快速的定位到错误的地方

大量的使用函数和方法返回 error,使得调用代码变得特别难看,也不优雅,一大堆的检查语句充实代码段间

可用的几种解决方法

1、使用定制的检查函数处理错误逻辑,简化检查,比如记录日志
2、在不影响逻辑的情况下,使用 defer 延后处理错误状态,err 退化赋值
3、在不中断逻辑的情况下,将错误作为内部状态保存,等最后面提交时再处理错误

panic、recover

与 error相比,panic/recover 使用方法上更接近 try/catch

panic 会立即中断当前函数流程,执行延时调用

而在延时函数中,recover 可捕获并返回 panic提交的错误对象

func main() {
	defer func() {
		if err := recover(); err != nil {
			log.Fatalln(err)
		}
	}()
	panic("触发异常")	// 引发异常
	println("退出。。。。")	// 永远不会执行
}
// 2022/09/23 16:01:11 触发异常

所有的延时调用不管如何,都会被执行,但中断错误会沿着调用堆栈向外传递

要么是被外层捕获,要么就是触发进程崩溃

func test() {
	defer println("test 1")
	defer println("test 2")

	panic("触发异常")
}
func main() {
	defer func() {
		if err := recover(); err != nil {
			log.Fatalln(err)
		}
	}()
	
	test()
}
// test 2
// test 1
// 2022/09/23 16:10:14 触发异常

还有当连续调用 panic时,又会被如何 recover捕获呢

func main() {
	defer func() {
		for {
			if err := recover(); err != nil {
				log.Fatalln(err)
			} else {
				log.Fatalln("未捕获到异常")
			}
		}
	}()

	defer func() {
		panic("再次触发异常")
	}()

	panic("触发异常")
}
// 2022/09/23 16:15:58 再次触发异常
// 只有最后一个会被 recover捕获

特别需要说一下的,recover必须在延时函数中执行才能生效

func main() {
	defer func() {
		log.Fatalln("test 1:", recover())
	}()
	defer println("test 2:", recover())
	defer recover()

	panic("触发异常")
}
// test 2: (0x0,0x0)
// 2022/09/23 16:23:06 test 1: 触发异常
// 可以看见只有延时函数中的 recover被生效

因为 recover这个特性,那么如果要保护某个代码片段,那么只能将其重构为函数再调用

func test(x, y int) interface{} {
	z := 0
	func() {
		defer func() {
			if err := recover(); err != nil {
				log.Println(err)
			}
		}()
		z = x / y
	}()
	return z
}

func main() {
	result := test(1, 0)
	fmt.Print("1 / 0 = ",result)
}
// 2022/09/23 16:38:31 runtime error: integer divide by zero
// 1 / 0 = 0
// 对 x / y 做了保护

写在最后

当然了,还是建议除非是不可恢复性、导致系统无法正常工作的错误,否则不建议使用 panic

比如:端口服务被占用、数据库连接失败、文件系统没有权限

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

paidx0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值