在Golang中与其他编程语言不太一样,没有 try
catch
捕获行为。
Golang 处理异常错误,通过函数返回的 err 类型, 或 panic
/ recover
。
下面这段代码相当于 try/catch 捕获。
package main
import (
"errors"
"fmt"
)
// 只要执行此函数一定会抛出异常
func errFunc() error {
return errors.New("type error")
}
func main() {
err := errFunc()
// 通过判断返回值,如果不是返回 nil 说明有异常
if err != nil {
fmt.Print(err)
} else {
// ...
}
}
panic
panic内置函数停止当前goroutine的正常执行,当函数F调用panic时,函数F的正常执行被立即停止,然后运行所有在F函数中的defer函数,然后F返回到调用他的函数对于调用者G,F函数的行为就像panic一样,终止G的执行并运行G中所defer函数,此过程会一直继续执行到goroutine所有的函数。panic可以通过内置的recover来捕获。
将上面的代码进行稍微改造下:
package main
import (
"errors"
"fmt"
)
// 只要执行此函数一定会抛出异常
func errFunc() error {
return errors.New("type error")
}
func main() {
err := errFunc()
// 通过判断返回值,如果不是返回 nil 说明有异常
if err != nil {
panic(err)
}
fmt.Print("一定不会执行到这里")
}
由于 err 发生了错误并执行 panic
使程序停止运行。
/private/var/folders/p_/np5btv6969b2nsyfp68q7_y00000gn/T/___go_build_app
panic: type error
goroutine 1 [running]:
main.main()
/app/main.go:19 +0x5a
Process finished with exit code 2
recover
recover内置函数用来管理含有panic行为的goroutine,recover运行在defer函数中
,获取panic抛出的错误值,并将程序恢复成正常执行的状态。如果在defer函数之外调用recover,那么recover不会停止并且捕获panic错误如果goroutine中没有panic或者捕获的panic的值为nil,recover的返回值也是nil。由此可见,recover的返回值表示当前goroutine是否有panic行为。
package main
import (
"errors"
"fmt"
)
func errFunc() error {
return errors.New("type error")
}
func main() {
err := errFunc()
defer func() {
if err := recover(); err != nil {
fmt.Print("起死回生")
}
}()
if err != nil {
panic(err)
}
}
recover 必须在 defer 语句,否则起不到作用。
总结
- 通过判断函数返回的 err 如果不为
nil
说明有异常。 - 调用 panic 会使整个程序终止运行。
- recover 必须运行在defer函数内,可以让 panic 错误起死回生。
- 考虑当前场景是否真正的需要使用
panic
,否则一般不要使用。