当前位置: 首页 > news >正文

第5章:Go语言错误处理和异常

第5章:Go语言错误处理和异常

5.1 错误类型基础

5.1.1 error接口

// error接口定义
type error interface {Error() string
}// 自定义错误
type CustomError struct {Message stringCode    int
}func (e *CustomError) Error() string {return fmt.Sprintf("错误码: %d, 信息: %s", e.Code, e.Message)
}

5.1.2 创建和使用错误

// 创建简单错误
func divide(a, b int) (int, error) {if b == 0 {return 0, errors.New("除数不能为零")}return a / b, nil
}func main() {result, err := divide(10, 0)if err != nil {fmt.Println("发生错误:", err)// 处理错误}
}

5.2 错误处理模式

5.2.1 多返回值错误处理

func readFile(filename string) ([]byte, error) {data, err := ioutil.ReadFile(filename)if err != nil {// 错误处理return nil, fmt.Errorf("读取文件失败: %v", err)}return data, nil
}func processFile(filename string) {data, err := readFile(filename)switch {case err == nil:// 正常处理fmt.Println(string(data))case os.IsNotExist(err):fmt.Println("文件不存在")case os.IsPermission(err):fmt.Println("权限不足")default:fmt.Println("未知错误:", err)}
}

5.2.2 错误类型断言

type ValidationError struct {Field stringValue interface{}
}func (e *ValidationError) Error() string {return fmt.Sprintf("验证错误:字段 %s 值 %v 不合法", e.Field, e.Value)
}func validateAge(age int) error {if age < 0 || age > 150 {return &ValidationError{Field: "Age",Value: age,}}return nil
}func main() {err := validateAge(-5)if err != nil {if ve, ok := err.(*ValidationError); ok {fmt.Printf("特定错误处理:%s\n", ve.Error())}}
}

5.3 panic和recover

5.3.1 panic触发

func riskyOperation() {panic("发生严重错误")
}func main() {riskyOperation()  // 程序将立即终止
}

5.3.2 recover捕获异常

func recoverExample() {defer func() {if r := recover(); r != nil {fmt.Println("捕获到panic:", r)// 可以进行日志记录、资源清理等}}()// 模拟可能发生panic的代码panic("unexpected error")
}func main() {recoverExample()fmt.Println("程序继续执行")
}

5.4 自定义错误处理

5.4.1 错误包装

func wrapError(err error) error {return fmt.Errorf("操作失败:%w", err)
}func complexOperation() error {// 模拟底层错误baseErr := errors.New("数据库连接失败")return wrapError(baseErr)
}func main() {err := complexOperation()// 错误解包if errors.Is(err, baseErr) {fmt.Println("匹配到原始错误")}
}

5.4.2 错误日志记录

type Logger struct {file *os.File
}func (l *Logger) LogError(err error) {if err != nil {logEntry := fmt.Sprintf("%s - Error: %v\n", time.Now().Format(time.RFC3339), err)l.file.WriteString(logEntry)}
}func main() {logger, _ := os.OpenFile("error.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)defer logger.Close()customLogger := &Logger{file: logger}err := someRiskyOperation()customLogger.LogError(err)
}

5.5 最佳实践

5.5.1 错误处理原则

  1. 始终检查错误
  2. 只处理可以处理的错误
  3. 在合适的抽象层级传播错误
  4. 避免忽略错误
  5. 使用错误包装增加上下文信息

5.5.2 常见错误处理模式

// 错误处理模式示例
func processData(data []byte) error {if len(data) == 0 {return errors.New("数据为空")}// 处理数据的复杂逻辑return nil
}func main() {data := []byte{}if err := processData(data); err != nil {log.Printf("处理失败:%v", err)// 根据不同错误类型采取不同处理策略return}
}

实践项目:简单的配置文件解析器

type Config struct {Database struct {Host stringPort int}
}func parseConfig(filename string) (*Config, error) {data, err := ioutil.ReadFile(filename)if err != nil {return nil, fmt.Errorf("读取配置文件失败: %w", err)}var config Configif err := json.Unmarshal(data, &config); err != nil {return nil, fmt.Errorf("解析配置文件失败: %w", err)}return &config, nil
}func main() {config, err := parseConfig("config.json")if err != nil {switch {case os.IsNotExist(err):log.Fatal("配置文件不存在")case os.IsPermission(err):log.Fatal("无权限读取配置文件")default:log.Fatalf("配置解析错误: %v", err)}}fmt.Printf("数据库配置:%+v\n", config.Database)
}
http://www.lryc.cn/news/516635.html

相关文章:

  • 题库刷题知识点总结
  • GraphRAG:LLM之Graphrag接入milvus
  • adb使用及常用命令
  • omnipeek分析beacon帧
  • Java数组问题
  • salesforce 可以为同一个简档的同一个 recordtype 的对象设置多种页面布局吗
  • 使用vue项目中,使用webpack模板和直接用vue.config来配置相关插件 区别是什么,具体有哪些提现呢
  • 五、包图
  • 关于重构一点简单想法
  • kafka使用以及基于zookeeper集群搭建集群环境
  • GAN对抗生成网络(二)——算法及Python实现
  • 并发线程(21)——线程池
  • 基于32单片机的智能语音家居
  • VScode怎么重启
  • 分析服务器 systemctl 启动gozero项目报错的解决方案
  • 大模型LLM-Prompt-OPTIMAL
  • 3. 多线程(1) --- 创建线程,Thread类
  • 简单的jmeter数据请求学习
  • 智能水文:ChatGPT等大语言模型如何提升水资源分析和模型优化的效率
  • 民宿酒店预订系统小程序+uniapp全开源+搭建教程
  • 计算机网络掩码、最小地址、最大地址计算、IP地址个数
  • Mac中配置vscode(第一期:python开发)
  • 软件项目体系建设文档,项目开发实施运维,审计,安全体系建设,验收交付,售前资料(word原件)
  • 计算机网络--路由表的更新
  • CDN防御如何保护我们的网络安全?
  • matlab离线安装硬件支持包
  • 使用virtualenv创建虚拟环境
  • Java链表
  • Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s
  • 解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域