#143·conc

在 `ErrorPool` 中,将错误存储为 `[]error` 而不是扁平化的 `error`

作者: akallu创建于 2024年11月6日更新于 2024年12月19日

在下面的代码片段中,我们可以看到错误是按顺序加入的: go func (p *ErrorPool) addErr(err error) { if err != nil { p.mu.Lock() if p.onlyFirstError { if p.errs == nil { p.errs = err } } else { p.errs = multierror.Join(p.errs, err) } p.mu.Unlock() } } 但是,如果没有递归函数,从 ErrorPool#Wait() 中获取底层错误会非常困难(当前的方法还以不最优的方式存储错误,导致更多的内存使用,但这并不是一个大问题): go func unwrapErrors(err error) []error { if err == nil { return nil } v, ok := err.(interface{ Unwrap() []error }) if !ok { return []error{err} } var errs []error for _, wErr := range v.Unwrap() { errs = append(errs, unwrapErrors(wErr)...) } return errs } 如果错误保留为 []error,并且 errors.Join(p.errs)ErrorPool#Wait() 中执行,则从中获取底层错误只需一行代码: res, err := myPool.Wait() errs := err.(interface{ Unwrap() []error }).Unwrap() 我不介意为这个工作做出努力,并且应该注意到,它与那些在野中创建了像上面的 unwrapErrors 这样的函数的人是相容的。

内容来源: sourcegraph/conc