Go 中 goroutine 不支持抛出异常,错误需显式传递;常用方式是通过 channel 接收 error,子协程执行完后发送 error 或 nil 到通道,主协程用 select 或直接接收等待结果,适用于单次明确任务。

Go 中 goroutine 本身不支持“抛出异常”,错误必须显式传递。捕获 goroutine 中的错误,核心思路是:不让错误消失在并发里,而是通过通道(channel)或回调等方式,把错误带回到主流程中处理。
用 channel 接收 error(最常用)
启动 goroutine 时,额外提供一个 chan error,让子协程执行完后把错误(或 nil)发进去。主 goroutine 用 select 或直接接收等待结果。
- 适合单次任务、有明确开始/结束的场景(比如一次 HTTP 请求、一次文件读取)
- 注意 channel 要足够缓冲,或用 go defer 发送,避免 goroutine 永久阻塞
- 示例:
err := doSomething()
errCh
}(errCh)
主流程:err := ,即可拿到错误。
返回值 channel + error channel 组合(推荐结构化)
对需要返回数据又可能出错的任务,定义两个通道:一个传结果(chan T),一个传错误(chan error)。调用方 select 等待任一通道就绪。
立即学习“go语言免费学习笔记(深入)”;
- 避免类型转换,语义清晰
- 可配合
context.Context实现超时取消,防止 goroutine 泄漏 - 示例函数签名:
func fetchUser(ctx context.Context, id int) (
用 sync.WaitGroup + 错误收集(适合批量并发)
当启动多个 goroutine 并行执行同类任务(如批量调用 API),可用 sync.WaitGroup 控制生命周期,配合 mutex + 共享 error 切片收集非致命错误。
- 适用于“尽量完成,汇总失败项”的场景
- 注意:只适合非关键错误;致命错误(如初始化失败)仍建议提前退出或单独通道通知
- 共享 error 变量需加锁,或用
atomic.Value存储第一个错误
封装成函数返回 error(隐藏 goroutine 细节)
如果业务逻辑本就不该暴露并发细节,可封装为同步函数,内部用 goroutine 执行但阻塞等待结果 —— 本质是“伪异步”,适合工具类方法。
- 例如:
result, err := DoWithTimeout(fn, time.Second) - 内部用
chan result+select超时控制,错误统一返回 - 调用方无感知并发,错误处理方式和普通函数一致
基本上就这些。关键是别让 error 在 goroutine 里被忽略或丢弃。选 channel 还是共享变量,取决于任务粒度、错误重要性以及是否需要响应速度。不复杂但容易忽略。










