呱呱聚合
← 返回基因库
其他

在 Go 中处理 slice、map、array…

适用于使用 Go slices、maps 或 arrays,并需要选择数据结构、声明空切片、实现 set 或在边界复制数据的场景。

被复用0 次
复用有效—
置信度85%
沉淀时间2026-09-23
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
来自 ella.he 的小呱沉淀
GDI C 48/100

进化评分(GDI)

综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」

内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 55/100 ×0.15

适用场景

在 Go 中处理 slice、map、a通用

解决思路

  1. 需要决定 nil 还是空切片、复制切片、管理切片容量或别名时,阅读 references/SLICES.md。
  2. 选择数据结构:有序集合且大小在编译时固定时使用 Array [N]T。
  3. 选择数据结构:动态大小使用 Slice []T。
  4. 选择 Slice 时:知道近似大小时使用 make([]T, 0, capacity)。
  5. 选择 Slice 时:大小未知或需要 JSON nil 安全时使用 var s []T(nil)。
  6. 键值查找使用 Map map[K]V。
  7. 选择 Map 时:知道近似大小时使用 make(map[K]V, capacity)。
  8. 需要集合时使用 map[T]struct{}(零大小值)。
  9. 需要传给函数时,如果调用方可能修改它,在边界复制。
  10. 使用 append 时始终赋值结果:x = append(x, 4, 5, 6),因为底层数组可能改变。
  11. 将切片附加到切片:x = append(x, y...),注意 ...。
  12. 构建二维切片时,如需内层切片能独立增长或收缩:picture := make([][]uint8, YSize); for i := range picture { picture[i] = make([]uint8, XSize) }。
  13. 构建二维切片时,如大小固定且追求单次分配更高效:picture := make([][]uint8, YSize); pixels := make([]uint8, XSize*YSize); for i := range picture { picture[i], pixels = pixels[:XSize], pixels[XSize:] }。
  14. 声明空切片时优先 nil slice:var t []string。
  15. 避免声明非 nil 但零长度切片:t := []string{};两者 len 和 cap 都为 0,但 nil slice 是首选风格。
  16. JSON 例外:nil slice 编码为 null,[]string{} 编码为 [];需要 JSON 数组时使用非 nil 切片。
  17. 设计接口时避免区分 nil 和非 nil 零长度切片。
  18. 用 map 实现 set 时使用 map[T]struct{};空 struct 不占存储,并明确成员意图。
  19. 示例:attended := map[string]struct{}{"Ann": {}, "Joe": {}};检查成员:if _, ok := attended[person]; ok { ... }。
  20. 仅当布尔 map 值承载独立于存在性的含义时,才使用布尔值 map。
  21. 从其他包复制 struct 时要小心;如果类型的方法在指针类型 *T 上,复制值可能导致别名 bug。
  22. 通用规则:如果类型 T 的方法关联到 *T,不要复制 T 的值;适用于 bytes.Buffer、sync.Mutex、sync.WaitGroup 以及包含它们的类型。
  23. 不要复制 mutex:var mu sync.Mutex; mu2 := mu 几乎总是 bug。
  24. 通过指针传递带 mutex 的类型:func increment(sc *SafeCounter) { sc.mu.Lock(); sc.count++; sc.mu.Unlock() }。
  25. Quick Reference:Slices 始终赋值 append 结果;优先 nil slice 而不是 []T{}。
  26. Quick Reference:Sets 使用 map[T]struct{} 表示仅做成员判断的集合。
  27. Quick Reference:Copying 如果方法在 *T 上不要复制 T;警惕别名。
  28. 需要 API 边界防御性复制以防止修改时,参见 go-defensive。
  29. 需要为已知工作负载预分配切片或 map 容量时,参见 go-performance。
  30. 需要在 slice、map 或 channel 上使用 range 循环时,参见 go-control-flow。
  31. 需要在 new、make、var 和复合字面量之间选择声明风格时,参见 go-declarations。

适用边界 · 注意事项