golang 入门(十) 异常处理
原创
©著作权归作者所有:来自51CTO博客作者hellowgw的原创作品,请联系作者获取转载授权,否则将追究法律责任
1、recovery捕获异常
代码在运行的时候,总会遇到错误。有的时候我们会希望程序遇到错误以后继续运行后面的流程,而不是直接异常退出。在Python中,使用try except组合实现这种需求,代码如下”
s = 0
try:
# 用5除以0,会造成计算结果异常
ret = 5/s
print("运行结果是 {}".format(ret))
except Exception as e:
print("我发现了异常 {}".format(e))
print("我还能继续运行到程序结束")
运行结果
% python main.py
我发现了异常 division by zero
我还能继续运行到程序结束
Go中没有类似try except这种语法,我们使用内置函数recovery()来替代except捕获异常,要注意recovery()必须与延迟执行函数defer()一起使用。代码如下:
package main
import "fmt"
func calc(s int) {
// 定义一个延迟的匿名函数并运行
defer func() {
// 捕获异常,并赋值给变量。相当于python中except部分的功能
err := recover()
if err != nil {
fmt.Println("我发现了异常: ", err)
}
}()
ret := 5 / s
fmt.Println("运行结果是: ", ret)
}
func main() {
calc(0)
fmt.Println("我还能继续运行到程序结束")
}
运行结果
% go run main.go
我发现了异常: runtime error: integer divide by zero
我还能继续运行到程序结束
2、panic触发异常
除了系统判断出来的程序异常外,我们也会有需求可以自己主动抛出异常来终止程序或进行错误预警。在python中,我们通过raise关键字来实现这个需求,代码如下:
s = 5
try:
ret = int(5/s)
# 程序没错,我也可以自己触发异常
raise Exception("运行结果< {} >是正确的,但我就想抛个异常出来".format(ret))
except Exception as e:
print("我发现了异常: {}".format(e))
print("我还能继续运行到程序结束")
运行结果
% python main.py
我发现了异常 运行结果< 1 >是正确的,但我就想抛个异常出来
我还能继续运行到程序结束
在Go中,我们通过panic来实现类似的效果
package main
import "fmt"
func calc(s int) {
// 定义一个延迟执行的匿名函数
defer func() {
// 捕获异常,并赋值给变量。相当于python中except部分的功能
if err := recover(); err != nil {
fmt.Println("我发现了异常: ", err)
}
}()
ret := 5 / s
fmt.Println("运行结果是: ", ret)
// 主动抛出异常信息,会被recover()捕获到,相当于python中raise关键字的作用
panic("运行结果是正确的,但我就想抛个异常出来")
}
func main() {
calc(5)
fmt.Println("我还能继续运行到程序结束")
}
运行结果
% go run main.go
运行结果是: 1
我发现了异常: 运行结果是正确的,但我就想抛个异常出来
我还能继续运行到程序结束
3、errors
虽然recover()和panic()组合可以实现类似于try..except的效果。但是Go其实不建议轻易使用panic抛异常的方式。推荐的做法是利用glang的函数可以返回多个值的特性。在返回执行的结果的同时,使用内置的错误类型errors描述函数的执行状态。
package main
import (
"errors"
"fmt"
)
// 返回值中包含error类型的数据
func calc(s int) (int, error) {
ret := 5 / s
if s > 1 {
// 定义error类型的描述内容并赋值
WgwAngry := errors.New(fmt.Sprintf("参数大于 1 就不行,现在传输的是 %d", s))
// 将运行结果置为0并将定义的错误描述返回给调用方
return 0, WgwAngry
}
// 未出现异常或错误,error对应的值返回nil即可
return ret, nil
}
func main() {
// 判断函数执行结果中,是否存在错误描述
if r, err := calc(5); err != nil {
// 打印自定义的错误信息
fmt.Println("自定义错误提示: ", err)
} else {
fmt.Println("程序运行结果:", r)
}
}
运行结果
% go run main.go
自定义错误提示: 参数大于 1 就不行,现在传输的是 5