记录一下自己的学习过程,顺带水一篇文章
go语言错误处理
错误处理基本思路
result, err := someFunction() //调用函数通常会返回一个值和一个错误对象。
if err != nil { //错误对象如果为nil,表示没有错误;否则,包含了关于该错误的信息
log.Fatal(err) //将错误写入日志并退出
}
自定义错误信息
type MyError struct {
Message string
}
func (e *MyError) Error() string {
return fmt.Sprintf("错误信息是:%s", e.Message)
}
错误处理方法
使用error包
//假设这是一个模拟除法的函数,n是除数
if n == 0 {
return 0, fmt.Errorf("无效的参数n: %d", n) //fmt.ERRorf可以格式化输出错误信息
return 0,errors.New("division by zero") //errors.New可以直接输出错误信息
}
日志记录
if err != nil {
log.Printf("someFunction执行错误: %v", err)//格式化并打印日志消息到标准错误输出 打印后继续执行程序
return err
}
错误传播(适用于函数调用) Wrap() 函数
file, err := openFile()
if err != nil {
return nil, errors.Wrap(err, "openFile 函数出错")
}
// 如果想让 Is 识别自定义错误类型需要实现 Unwrap 方法
func (e *FoundFile) Unwrap() error {
return e.Err
}
_, err := readFile()
if errors.Is(err, ErrFileNotFound) { //errors.Is() 函数会从错误包裹中查找是否存在指定类型的错误,
fmt.Printf("%+v", err)
}
panic()和recover()
panic 会使程序立即停止,并输出错误信息
需要使用 recover 来捕获并处理这些错误
defer func() {
if err := recover(); err != nil {
fmt.Println("发生错误:", err)
// 执行一些恢复操作
}
}()
if _,err = somefunc; err!=nil {
panic(err)
}
在使用 panic 时,需要注意以下几点:
-
panic 会导致当前函数的执行立即停止,但defer语句会被正常执行。
-
如果当前函数中没有捕获 panic 的 recover 语句,程序会从当前函数逐层向上返回,并终止程序的执行。
-
panic 传递的信息可以是任意类型的值,通常使用字符串或自定义的错误类型。
-
可以在 defer 语句中使用 panic,但必须在 panic 被触发前定义 defer 语句。
-
通常建议在顶层函数中使用 recover 来捕获并处理 panic,以防止程序意外终止。