
一、error 错误处理1. error 底层本质error是 Go 内置接口仅定义一个Error() string方法gotype error interface { Error() string }只要类型实现该方法就满足error接口用于非致命、可处理的常规错误。2. 两种创建 error 的方式errors.New(错误信息)纯静态字符串错误fmt.Errorf(格式化模板, 参数)支持格式化拼接错误信息gopackage main import ( errors fmt ) func main() { // 方式1errors.New err1 : errors.New(this is err2) fmt.Println(err1.Error()) // 方式2fmt.Errorf 支持格式化 err2 : fmt.Errorf(%s, this is normal err1) fmt.Println(err2.Error()) }3. 实战案例除法函数错误返回业务函数通过多返回值返回结果 error调用方判断err ! nil处理错误Go 最标准错误写法go// MyDiv 除法运算分母为0返回error func MyDiv(a, b int) (int, error) { if b 0 { // 构造错误返回 return 0, errors.New(分母不能为0) } return a / b, nil // 无错误返回nil } func main() { result, err : MyDiv(10, 2) if err ! nil { // 存在错误打印错误信息 fmt.Println(err , err) } else { // 无错误正常使用结果 fmt.Println(result , result) } }核心规范正常业务错误优先使用error不要轻易 panic。二、panic 恐慌1. panic 适用场景发生不可预期、致命、无法继续执行的错误时触发主动显式调用panic(错误信息)运行时异常自动触发数组 / 切片越界、nil 指针解引用、类型断言失败等2. 示例 1手动触发 panicgofunc testa() { fmt.Println(aaaaaaaaaaa) } func testb() { // 主动抛出panic程序会终止无recover时 panic(this is a panic test) } func main() { testa() testb() fmt.Println(这段代码不会执行) }3. 示例 2运行时数组越界自动 panicgo// x传入超过数组下标范围会触发panic func testb(x int) { var arr [10]int // 下标 0~9 arr[x] 111 // x20 数组越界自动panic } func main() { testb(20) }panic 执行流程触发 panic 后停止当前函数正常执行逆序执行当前协程所有defer延迟函数若无recover捕获程序直接崩溃退出打印堆栈信息三、recover 捕获 panic核心规则recover()只能写在defer 延迟匿名函数内部才生效无 panic 时recover()返回nil捕获到 panic 时返回 panic 传入的错误值阻断程序崩溃一次 defer 中调用一次 recover 即可重复调用无意义完整可运行案例数组越界 panic 自动恢复gopackage main import fmt func testb(x int) { // defer 匿名函数 内置recover捕获panic defer func() { // 接收panic信息 if err : recover(); err ! nil { fmt.Println(捕获到panic, err) } // recover() 无需重复调用 }() // 匿名函数立即注册到defer var arr [10]int arr[x] 111 // 越界触发panic fmt.Println(正常执行逻辑) } func main() { testb(20) // recover捕获panic后程序不会退出后续代码正常运行 fmt.Println(程序成功恢复继续执行main函数) }四、error vs panic 核心区分表格特性error普通错误panic恐慌异常使用场景可预期、业务常规错误致命、不可预期运行异常处理方式函数返回值手动判断err!nildeferrecover 捕获恢复程序行为不中断程序可继续运行无 recover 直接崩溃退出设计定位业务逻辑错误运行时严重 bug、非法操作使用建议接口参数校验、文件读写失败、数据库查询失败 →用 error 返回数组越界、非法内存操作、初始化严重失败等不可控异常 → panic recover 兜底五、完整整合可运行 Demo复制直接跑gopackage main import ( errors fmt ) // 1. error 示例除法 func MyDiv(a, b int) (int, error) { if b 0 { return 0, errors.New(分母不能为0) } return a / b, nil } // 2. panic recover 示例数组越界捕获 func arrayTest(x int) { defer func() { if err : recover(); err ! nil { fmt.Printf(捕获panic异常%v\n, err) } }() var arr [10]int arr[x] 999 fmt.Println(数组赋值成功) } func main() { // error测试 res, err : MyDiv(10, 0) if err ! nil { fmt.Println(除法错误, err) } else { fmt.Println(除法结果, res) } fmt.Println() // panic recover测试 arrayTest(20) fmt.Println(main函数执行完毕程序未崩溃) }总结error是接口两种生成方式errors.New/fmt.ErrorfGo 约定函数出错通过多返回值返回 error调用方必须判断panic 分为手动调用、运行时异常自动触发两种recover 必须写在 defer 匿名函数中否则无法捕获 panic业务优先 error底层严重异常使用 panicrecover 做容错兜底