代码示例
package main
import (
"fmt"
"os"
)
// 定义文件读取错误类型
type FileReadError struct {
ErrMsg string
}
func (e *FileReadError) Error() string {
return e.ErrMsg
}
// 定义数据解析错误类型
type DataParseError struct {
ErrMsg string
}
func (e *DataParseError) Error() string {
return e.ErrMsg
}
// 文件读取模块函数
func readFile(filePath string) ([]byte, error) {
data, err := os.ReadFile(filePath)
if err != nil {
if os.IsNotExist(err) {
return nil, &FileReadError{ErrMsg: "文件不存在"}
}
if os.IsPermission(err) {
return nil, &FileReadError{ErrMsg: "权限不足"}
}
return nil, err
}
return data, nil
}
// 数据解析模块函数
func parseData(data []byte) (string, error) {
// 这里简单示例,假设数据解析失败条件
if len(data) == 0 {
return "", &DataParseError{ErrMsg: "数据格式错误"}
}
return string(data), nil
}
// 主函数
func main() {
filePath := "test.txt"
data, err := readFile(filePath)
if err != nil {
if fileErr, ok := err.(*FileReadError); ok {
fmt.Printf("文件读取错误: %v\n", fileErr.Error())
} else {
fmt.Printf("其他文件读取错误: %v\n", err)
}
return
}
result, err := parseData(data)
if err != nil {
if parseErr, ok := err.(*DataParseError); ok {
fmt.Printf("数据解析错误: %v\n", parseErr.Error())
} else {
fmt.Printf("其他数据解析错误: %v\n", err)
}
return
}
fmt.Printf("解析结果: %s\n", result)
}
解释
- 定义错误类型:
- 为文件读取和数据解析分别定义了
FileReadError
和DataParseError
结构体类型,并实现error
接口。这样不同模块的错误类型清晰,有利于模块间解耦。
- 文件读取模块函数:
readFile
函数负责读取文件,使用os.ReadFile
进行文件读取。如果发生错误,根据错误类型判断是文件不存在还是权限不足,返回对应的自定义错误。其他未知错误直接返回。
- 数据解析模块函数:
parseData
函数负责数据解析,简单示例中如果数据长度为0则返回数据格式错误的自定义错误。
- 主函数:
- 在主函数中依次调用文件读取和数据解析函数。如果发生错误,使用类型断言判断错误类型,根据不同类型的错误进行相应处理,既能有效传递和处理错误,又保持了模块之间的低耦合性。不同模块只需关心自己的错误类型,而不需要了解其他模块内部的错误实现细节。