Go语言学习笔记之错误和异常详解
作者:鹿鱼 时间:2024-02-05 11:39:15
错误
Go 语言通过内置的错误接口提供了非常简单的错误处理机制,Error 类型是一个接口类型。
type error interface {
Error() string
}
可以在编码中通过实现 error 接口类型来生成错误信息。
函数通常在最后的返回值中返回错误信息。
// 定义一个 DivideError 结构
type DivideError struct {
dividee int
divider int
}
// 实现 `error` 接口
func (de *DivideError) Error() string {
strFormat := `
Cannot proceed, the divider is zero.
dividee: %d
divider: 0
`
return fmt.Sprintf(strFormat, de.dividee)
}
func Divide(varDividee int, varDivider int) (result int, errorMsg string) {
if varDivider == 0 {
dData := DivideError{
dividee: varDividee,
divider: varDivider,
}
errorMsg = dData.Error()
return
} else {
return varDividee / varDivider, ""
}
}
Divide 函数传入除数和被除数,当被除数为零时,函数抛出异常。
if result, errorMsg := Divide(100, 10); errorMsg == "" {
fmt.Println(result)
}
这是正常情况下。
当除数为零的时候会返回错误信息。
if _, errorMsg := Divide(100, 0); errorMsg != "" {
fmt.Println("errorMsg is: ", errorMsg)
}
异常
Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、空指针引用等。这些运行时错误会引起painc异常。
当程序发生异常时,无法继续运行,使用 panic
来终止程序。
应该尽可能地使用错误,而不是使用 panic
和 recover
。只有当程序不能继续运行的时候,才应该使用 panic
和 recover
机制。
panic
有两个合理的用例:
发生了一个不能恢复的错误,此时程序不能继续运行。
发生了一个编程上的错误。一个接收指针参数的方法,而其他人使用
nil
作为参数调用了它。在这种情况下,可以使用panic
,因为这是一个编程错误:用nil
参数调用了一个只能接收合法指针的方法。
内建函数 panic
:
func panic(v interface{})
当程序终止时,会打印传入 panic
的参数。
package main
func main() {
panic("panic error")
}
会打印出传入 panic
函数的信息,并打印出堆栈跟踪。
recover
是一个内建函数,用于重新获得 panic
协程的控制。
func recover() interface{}
recover
必须在 defer
函数中才能生效,在延迟函数内调用 recover
,可以取到 panic
的错误信息,并且停止 panic
续发事件。只有在相同的协程中调用 recover
才管用, recover
不能恢复一个不同协程的 panic
。
package main
import "fmt"
func outOfArray(x int) {
defer func() {
// recover() 可以将捕获到的 panic 信息打印
if err := recover(); err != nil {
fmt.Println(err)
}
}()
var array [5]int
array[x] = 1
}
func main() {
// 故意制造数组越界 触发 panic
outOfArray(20)
// 如果能执行到这句 说明 panic 被捕获了
// 后续的程序能继续运行
fmt.Println("main...")
}
来源:https://juejin.cn/post/7123831661782892581