
go 中无法直接用 try-catch,但可通过 defer + recover 在循环内捕获 panic,使程序跳过异常项继续下一次迭代;关键在于将 recover 逻辑置于每次循环迭代的独立作用域中(如在 for 循环体内使用匿名函数或封装为辅助函数)。
go 中无法直接用 try-catch,但可通过 defer + recover 在循环内捕获 panic,使程序跳过异常项继续下一次迭代;关键在于将 recover 逻辑置于每次循环迭代的独立作用域中(如在 for 循环体内使用匿名函数或封装为辅助函数)。
在 Go 中,panic 会立即中断当前 goroutine 的执行流,若不显式恢复(recover),程序将终止。与 Java 的 try-catch 不同,Go 的错误处理强调显式错误返回(如 error 类型),而 panic/recover 仅适用于真正异常、不可恢复的场景(如空指针解引用、越界访问等)。但当需在循环中容忍个别操作失败并继续执行时,可借助 defer + recover 实现类似“跳过失败项”的效果——前提是 recover 必须在 panic 发生的同一 goroutine 且同一函数调用栈中生效。
⚠️ 原代码的问题在于:arr 是长度为 5 的切片([]int{5,6,7,8,9}),却试图通过 arr[6] = i 写入索引 6,触发运行时 panic(index out of range)。更严重的是,defer 被放在 for 循环外部(实际在 main 函数作用域注册),导致 recover() 只会在 main 函数结束时执行,而此时 panic 已经导致程序崩溃,无法捕获。
✅ 正确做法是:将 defer + recover 移入每次循环迭代内部,确保每个迭代拥有独立的 panic 捕获上下文。以下是推荐写法:
defer
-
优先避免 panic:对切片操作应先检查边界(
if index ),或使用append动态扩容; -
用 error 替代 panic:将易错逻辑封装为返回
(value, error)的函数,配合if err != nil { continue }; -
慎用 recover:仅用于顶层错误兜底(如 HTTP handler)、测试模拟或极少数必须“吞掉” panic 的场景;生产代码中滥用
recover会掩盖真实 bug。
总结:Go 中实现“循环内容错继续”,核心是确保 recover() 与 panic() 处于同一函数调用栈,且 defer 绑定在可能 panic 的最小作用域内。永远记住:panic 不是错误处理机制,而是异常终止信号;健壮性应来自预防,而非事后抢救。










