golang - 异常处理
基本的异常处理
目前流行的语言错误处理都是通过 try catch finally 关键字或类关键字处理的
但是在 golang 中提供了一些全新模式, 不同于 try catch 语句, go语言通过函数返回错误来捕获, go内置了error接口, 只要实现Error() string方法, 通过判断 err 是否是 nil 来捕获异常.
func div(x float32, y float32) (result float32, err error) {}
golang 中提供了 defer 关键字, 这个语句会在执行完当前函数后执行, 类似 finally
func main() {
// 相当于finally
defer println("done!")
println("hello, world")
}
举个具体的例子:
package main
import (
"fmt"
"math"
)
// 声明零除错误
type ZeroDivError struct {
code int
message string
}
// 实现error接口
func (e ZeroDivError) Error() string {
return fmt.Sprintf("%v: %v", e.code, e.message)
}
func div(x float32, y float32) (result float32, err error) {
if y == 0 {
return float32(math.Inf(1)), ZeroDivError{1, "零除问题"}
}
return x / y, err
}
func main() {
// 相当于finally
defer func() {
println("done!")
}
// 这个相当于
// try { r := div(1, 0) } catch e { println(r, e.Error() }
r, e := div(1, 0)
if e != nil {
println(r, e.Error())
}
}
panic 和 recover
golang 还提供了两个关键字 panic 和 recover, 按照上面的异常处理方式需要把错误一层一层的传递出去, 这两个关键字主要目的是用来做跨层级的异常捕获.
panic 用来立马中断当前程序返回异常, recover 用来捕获 panic 异常程序会继续执行
recover 只能在 defer 中才可以生效
panic 可以多次执行, 调用 recover 时会按顺序捕获错误
package main
import "fmt"
func a() {
defer func() {
e := recover()
fmt.Printf("a e: %v\n", e)
println("a done!")
}()
panic("a fatal!")
}
func b() {
defer func() {
e := recover()
fmt.Printf("b e: %v\n", e)
println("b done!")
}()
panic("b fatal!")
}
func main() {
defer func() {
e := recover()
fmt.Printf("main e: %v\n", e)
println("main done!")
}()
a()
b()
panic("main fatal!")
}
执行结果
a e: a fatal!
a done!
b e: b fatal!
b done!
main e: main fatal!
main done!

浙公网安备 33010602011771号