go语言中经常犯的错误( 三 )

如果 DBError 被包装,它永远不会触发重试 。
5、切片初始化有时,我们知道切片的最终长度是多少 。例如,假设我们要将 Foo 的切片转换为 Bar 的切片,这意味着这两个切片将具有相同的长度 。
我们有时候经常会这样初始化切片:
var bars []Barbars := make([]Bar, 0)我们都知道切片的底层是数组 。如果没有更多可用空间,它会实施增长战略 。在这种情况下,会自动创建一个新数组(容量更大)并复制所有元素 。
现在,假设我们需要多次重复这个增长操作,因为我们的 []Foo 包含数千个元素?插入的摊销时间复杂度(平均值)将保持为 O(1),但在实践中,它会对性能产生影响 。
因此,如果我们知道最终长度,我们可以:

  • 使用预定义的长度对其进行初始化:
  • func convert(foos []Foo) []Bar { bars := make([]Bar, len(foos)) for i, foo := range foos { bars[i] = fooToBar(foo) } return bars }
  • 或者使用 0 长度和预定义容量对其进行初始化:
  • func convert(foos []Foo) []Bar { bars := make([]Bar, 0, len(foos)) for _, foo := range foos { bars = Append(bars, fooToBar(foo)) } return bars }
选哪个更好呢?第一个稍微快一点 。然而,你可能更喜欢第二个,因为无论我们是否知道初始大小,在切片末尾添加一个元素都是使用 append 完成的 。
6、上下文管理context.Context对我们来说非常好用,他可以在协程之间传递数据、可以控制协程的生命周期等等 。但是这也造成了它的滥用 。
go官方文档是这么定义的:


推荐阅读