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

【Go 】异常处理

1. Go 语言错误处理基础

  • Go 语言尽量避免使用异常,推荐使用 返回错误 让调用者处理。
  • Go 语言标准库提供 error 接口:
    type error interface {
        Error() string
    }
    
  • errors.New("错误信息") 创建错误对象。
package main

import (
	"errors"
	"fmt"
)

func hello(name string) error {
	if len(name) == 0 {
		return errors.New("NameError: name is empty!!")
	}
	fmt.Println("hello !", name)
	return nil
}

func main() {
	err := hello("")
	if err != nil {
		fmt.Println("发生错误:", err)
	}
}

2. 自定义错误

  • errors.New() 生成错误信息
  • fmt.Errorf() 格式化错误信息
  • 返回错误让调用者决定如何处理
package main

import (
	"errors"
	"fmt"
)

func divide(a, b int) (int, error) {
	if b == 0 {
		return 0, errors.New("除数不能为0")
	}
	return a / b, nil
}

func main() {
	result, err := divide(10, 0)
	if err != nil {
		fmt.Println("计算错误:", err)
	} else {
		fmt.Println("计算结果:", result)
	}
}

3. panicrecover

  • panic 类似于 Python 的 raise,会让程序崩溃。
  • recover 用于捕获 panic,防止程序崩溃。
  • recover 必须在 defer 语句中调用,否则无效。
package main

import "fmt"

func safeFunction() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("捕获到 panic:", r)
		}
	}()
	fmt.Println("执行函数...")
	panic("故意触发 panic") // 触发 panic
}

func main() {
	safeFunction()
	fmt.Println("程序继续执行...")
}

4. panic 与数组越界

  • 数组访问越界会引发 panic,所以要提前检查索引范围。
package main

import (
	"errors"
	"fmt"
)

func getElement(index int) (int, error) {
	arr := [3]int{10, 20, 30}
	if index < 0 || index >= len(arr) {
		return 0, errors.New("索引超出范围")
	}
	return arr[index], nil
}

func main() {
	elem, err := getElement(3)
	if err != nil {
		fmt.Println("错误:", err)
	} else {
		fmt.Println("元素:", elem)
	}
}

5. defer 关键字

  • defer 语句用于延迟执行,常用于 释放资源、错误恢复等场景
  • 多个 defer先进后出(LIFO) 执行。
package main

import "fmt"

func deferTest() {
	defer fmt.Println("defer 1")
	defer fmt.Println("defer 2")
	fmt.Println("正常执行")
}

func main() {
	deferTest()
}

执行顺序:

正常执行
defer 2
defer 1

6. 处理文件操作错误

  • 文件操作涉及错误处理,os.OpenFile() 返回 error,要检查是否为 nil
package main

import (
	"fmt"
	"os"
)

func openFile() {
	file, err := os.OpenFile("test.txt", os.O_RDONLY, 0666)
	if err != nil {
		fmt.Println("打开文件失败:", err)
		return
	}
	defer file.Close()
	fmt.Println("文件打开成功")
}

func main() {
	openFile()
}

7. recover 结合 defer 进行异常恢复

  • recover() 只能在 defer 内部使用,否则无法捕获 panic
  • 可以用 recover 拦截异常,防止整个程序崩溃
package main

import "fmt"

func safeRun() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("捕获异常:", r)
		}
	}()
	panic("这是一个 panic 例子")
}

func main() {
	safeRun()
	fmt.Println("程序没有崩溃,继续执行")
}

8. 手动 panic

  • panic() 直接终止当前函数,沿调用栈向上传播。
  • 通常用于 不可恢复的严重错误(如数组越界)。
package main

import "fmt"

func checkIndex(index int) {
	if index < 0 {
		panic("索引不能为负数")
	}
	fmt.Println("索引有效:", index)
}

func main() {
	checkIndex(1)
	checkIndex(-1) // 这里会触发 panic
}

http://www.dtcms.com/a/81055.html

相关文章:

  • SpringBoot第四站(1):数据层开发: 配置数据源,整合jdbcTemplate
  • Linux文件挂载新文件夹,隐藏老文件夹问题
  • 【React】useEffect、useLayoutEffect底层机制
  • docker desktop 集成WSL Ubuntu22.04
  • FPGA----完美解决Windows下[XSIM 43-3409][XSIM 43-3915]错误
  • 自定义myshell(精讲)
  • 服务器相关的硬件知识
  • Ae 效果详解:描边
  • 空调遥控器低功耗单片机方案
  • Qt6+QML实现Windows屏幕录制
  • 云原生网络拓扑:服务网格的量子纠缠效应
  • Agilent N5230A矢量网络分析仪测试散射参数(S参数)步骤
  • RabbitMQ实现定时/延迟任务
  • 力扣 Hot 100 刷题记录 - 二叉搜索树中第 K 小的元素
  • Rust与Java对比
  • 【redis】AOF 的基本工作机制,顺序写入,文件同步,重写机制
  • lunar是一款无第三方依赖的公历 python调用
  • OSCP - Proving Grounds- CVE-2023-46818
  • 5-1 使用ECharts将MySQL数据库中的数据可视化
  • NLua 文档
  • Facebook的社交媒体伦理:信息传播与责任的平衡
  • Java集成MQTT和Kafka实现稳定、可靠、高性能的物联网消息处理系统
  • C语言未定义的标识符怎么解决
  • [创业之路-340]:投资的本质:前人栽树后人乘凉。企业固定资产投资
  • 论文速递| ECG去噪新方法:小波+ CNN提升可穿戴精度
  • Uni-App 双栏联动滚动组件开发详解 (电梯导航)
  • 【JVM】性能监控与调优概述篇
  • 面试提问:数仓设计不分层可以吗?
  • 关于 51 单片机显示多个数码管时出现残影
  • 基于springboot的高校心理教育辅导系统(019)