golang-data-structures
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePersona: You are a Go engineer who understands data structure internals. You choose the right structure for the job — not the most familiar one — by reasoning about memory layout, allocation cost, and access patterns.
角色定位: 你是一名精通数据结构内部实现的Go工程师。你会通过考量内存布局、分配成本和访问模式,为任务选择最合适的结构——而非最熟悉的结构。
Go Data Structures
Go数据结构
Built-in and standard library data structures: internals, correct usage, and selection guidance. For safety pitfalls (nil maps, append aliasing, defensive copies) see skill. For channels and sync primitives see skill. For string/byte/rune choice see skill.
samber/cc-skills-golang@golang-safetysamber/cc-skills-golang@golang-concurrencysamber/cc-skills-golang@golang-design-patterns内置及标准库数据结构:内部实现、正确用法与选型指南。关于安全陷阱(nil映射、append别名、防御性复制),请查看技能。关于通道与同步原语,请查看技能。关于string/byte/rune的选择,请查看技能。
samber/cc-skills-golang@golang-safetysamber/cc-skills-golang@golang-concurrencysamber/cc-skills-golang@golang-design-patternsBest Practices Summary
最佳实践总结
- Preallocate slices and maps with /
make(T, 0, n)when size is known or estimable — avoids repeated growth copies and rehashingmake(map[K]V, n) - Arrays SHOULD be preferred over slices only for fixed, compile-time-known sizes (hash digests, IPv4 addresses, matrix dimensions)
- NEVER rely on slice capacity growth timing — the growth algorithm changed between Go versions and may change again; your code should not depend on when a new backing array is allocated
- Use for priority queues,
container/heaponly when frequent middle insertions are needed,container/listfor fixed-size circular bufferscontainer/ring - MUST be preferred for building strings;
strings.BuilderMUST be preferred for bidirectional I/O (implements bothbytes.Bufferandio.Reader)io.Writer - Generic data structures SHOULD use the tightest constraint possible — for keys, custom interfaces for ordering
comparable - MUST only follow the 6 valid conversion patterns from the Go spec — NEVER store in a
unsafe.Pointervariable across statementsuintptr - (Go 1.24+) SHOULD be used for caches and canonicalization maps to allow GC to reclaim entries
weak.Pointer[T]
- 预分配切片和映射:当已知或可估算大小时,使用/
make(T, 0, n)——避免重复的增长复制和重哈希make(map[K]V, n) - 数组:仅当大小固定且编译时已知时(如哈希摘要、IPv4地址、矩阵维度),才应优先于切片使用
- 绝不依赖切片容量增长时机:Go版本间的增长算法已发生变化,未来可能再次变更;代码不应依赖后备数组的分配时机
- 使用实现优先队列,仅在需要频繁中间插入时使用
container/heap,使用**container/list**实现固定大小的循环缓冲区container/ring - **必须优先用于字符串构建;
strings.Builder**必须优先用于双向I/O(同时实现bytes.Buffer和io.Reader)io.Writer - 泛型数据结构应使用最严格的约束——键使用,排序使用自定义接口
comparable - ****必须仅遵循Go规范中的6种有效转换模式——绝不能跨语句存储在
unsafe.Pointer变量中uintptr - (Go 1.24+)应用于缓存和规范化映射,以允许GC回收条目
weak.Pointer[T]
Slice Internals
切片内部实现
A slice is a 3-word header: pointer, length, capacity. Multiple slices can share a backing array (→ see for aliasing traps and the header diagram).
samber/cc-skills-golang@golang-safety切片是一个3字长的头部:指针、长度、容量。多个切片可以共享同一个后备数组(→ 关于别名陷阱和头部示意图,请查看)。
samber/cc-skills-golang@golang-safetyCapacity Growth
容量增长
- < 256 elements: capacity doubles
-
= 256 elements: grows by ~25% ()
newcap += (newcap + 3*256) / 4 - Each growth copies the entire backing array — O(n)
- 元素数 < 256:容量翻倍
- 元素数 >= 256:增长约25%()
newcap += (newcap + 3*256) / 4 - 每次增长都会复制整个后备数组——时间复杂度O(n)
Preallocation
预分配
go
// Exact size known
users := make([]User, 0, len(ids))
// Approximate size known
results := make([]Result, 0, estimatedCount)
// Pre-grow before bulk append (Go 1.21+)
s = slices.Grow(s, additionalNeeded)go
// 已知精确大小
users := make([]User, 0, len(ids))
// 已知近似大小
results := make([]Result, 0, estimatedCount)
// 批量追加前预增长(Go 1.21+)
s = slices.Grow(s, additionalNeeded)slices
Package (Go 1.21+)
slicesslices
包(Go 1.21+)
slicesKey functions: /, , , , . For , , → see skill.
SortSortFuncBinarySearchContainsCompactGrowCloneEqualDeleteFuncsamber/cc-skills-golang@golang-safetySlice Internals Deep Dive — Full package reference, growth mechanics, vs , header copying, backing array aliasing.
sliceslencap核心函数:/、、、、。关于、、→ 请查看技能。
SortSortFuncBinarySearchContainsCompactGrowCloneEqualDeleteFuncsamber/cc-skills-golang@golang-safety切片内部实现深度解析——完整的包参考、增长机制、与对比、头部复制、后备数组别名。
sliceslencapMap Internals
映射内部实现
Maps are hash tables with 8-entry buckets and overflow chains. They are reference types — assigning a map copies the pointer, not the data.
映射是带有8条目桶和溢出链的哈希表。它们是引用类型——赋值映射时仅复制指针,而非数据。
Preallocation
预分配
go
m := make(map[string]*User, len(users)) // avoids rehashing during populationgo
m := make(map[string]*User, len(users)) // 避免填充期间的重哈希maps
Package Quick Reference (Go 1.21+)
mapsmaps
包快速参考(Go 1.21+)
maps| Function | Purpose |
|---|---|
| Build map from iterator |
| Insert entries from iterator |
| Iterator over all entries |
| Iterators over keys/values |
For , , sorted iteration → see skill.
CloneEqualsamber/cc-skills-golang@golang-safetyMap Internals Deep Dive — How Go maps store and hash data, bucket overflow chains, why maps never shrink (and what to do about it), comparing map performance to alternatives.
| 函数 | 用途 |
|---|---|
| 从迭代器构建映射 |
| 从迭代器插入条目 |
| 遍历所有条目 |
| 遍历键/值 |
关于、、排序迭代→ 请查看技能。
CloneEqualsamber/cc-skills-golang@golang-safety映射内部实现深度解析——Go映射如何存储和哈希数据、桶溢出链、映射为何从不收缩(以及解决方法)、映射性能与替代方案的对比。
Arrays
数组
Fixed-size, value types. Copied entirely on assignment. Use for compile-time-known sizes:
go
type Digest [32]byte // fixed-size, value type
var grid [3][3]int // multi-dimensional
cache := map[[2]int]Result{} // arrays are comparable — usable as map keysPrefer slices for everything else — arrays cannot grow and pass by value (expensive for large sizes).
固定大小的值类型。赋值时会完全复制。用于编译时已知大小的场景:
go
type Digest [32]byte // 固定大小的值类型
var grid [3][3]int // 多维数组
cache := map[[2]int]Result{} // 数组可比较——可用作映射键其他场景优先使用切片——数组无法增长,且按值传递(大尺寸时开销高昂)。
container/ Standard Library
container/标准库
| Package | Data Structure | Best For |
|---|---|---|
| Doubly-linked list | LRU caches, frequent middle insertion/removal |
| Min-heap (priority queue) | Top-K, scheduling, Dijkstra |
| Circular buffer | Rolling windows, round-robin |
| Buffered reader/writer/scanner | Efficient I/O with small reads/writes |
Container types use (no type safety) — consider generic wrappers. Container Patterns, bufio, and Examples — When to use each container type, generic wrappers to add type safety, and patterns for efficient I/O.
anybufio| 包 | 数据结构 | 最佳适用场景 |
|---|---|---|
| 双向链表 | LRU缓存、频繁中间插入/删除 |
| 最小堆(优先队列) | Top-K、调度、Dijkstra算法 |
| 循环缓冲区 | 滚动窗口、轮询 |
| 缓冲读取器/写入器/扫描器 | 小读写的高效I/O |
容器类型使用(无类型安全)——可考虑泛型包装器。容器模式、bufio及示例——何时使用每种容器类型、添加类型安全的泛型包装器、以及高效I/O的模式。
anybufiostrings.Builder vs bytes.Buffer
strings.Builder vs bytes.Buffer
Use for pure string concatenation (avoids copy on ), when you need or byte manipulation. Both support . Details and comparison
strings.BuilderString()bytes.Bufferio.ReaderGrow(n)纯字符串拼接使用(避免时的复制),需要或字节操作时使用。两者均支持。详情与对比
strings.BuilderString()io.Readerbytes.BufferGrow(n)Generic Collections (Go 1.18+)
泛型集合(Go 1.18+)
Use the tightest constraint possible. for map keys, for sorting, custom interfaces for domain-specific ordering.
comparablecmp.Orderedgo
type Set[T comparable] map[T]struct{}
func (s Set[T]) Add(v T) { s[v] = struct{}{} }
func (s Set[T]) Contains(v T) bool { _, ok := s[v]; return ok }Writing Generic Data Structures — Using Go 1.18+ generics for type-safe containers, understanding constraint satisfaction, and building domain-specific generic types.
使用最严格的约束。键使用,排序使用,领域特定排序使用自定义接口。
comparablecmp.Orderedgo
type Set[T comparable] map[T]struct{}
func (s Set[T]) Add(v T) { s[v] = struct{}{} }
func (s Set[T]) Contains(v T) bool { _, ok := s[v]; return ok }编写泛型数据结构——使用Go 1.18+泛型实现类型安全的容器、理解约束满足、以及构建领域特定的泛型类型。
Pointer Types
指针类型
| Type | Use Case | Zero Value |
|---|---|---|
| Normal indirection, mutation, optional values | |
| FFI, low-level memory layout (6 spec patterns only) | |
| Caches, canonicalization, weak references | N/A |
Pointer Types Deep Dive — Normal pointers, (the 6 valid spec patterns), and for GC-safe caches that don't prevent cleanup.
unsafe.Pointerweak.Pointer[T]| 类型 | 适用场景 | 零值 |
|---|---|---|
| 普通间接引用、修改、可选值 | |
| FFI、底层内存布局(仅6种规范模式) | |
| 缓存、规范化、弱引用 | N/A |
指针类型深度解析——普通指针、(6种有效规范模式)、以及用于GC安全缓存(不阻止清理)的。
unsafe.Pointerweak.Pointer[T]Copy Semantics Quick Reference
复制语义快速参考
| Type | Copy Behavior | Independence |
|---|---|---|
| Value (deep copy) | Fully independent |
| Value (deep copy) | Fully independent |
| Header copied, backing array shared | Use |
| Reference copied | Use |
| Reference copied | Same channel |
| Address copied | Same underlying value |
| Value copied (type + value pair) | Depends on held type |
| 类型 | 复制行为 | 独立性 |
|---|---|---|
| 值复制(深拷贝) | 完全独立 |
| 值复制(深拷贝) | 完全独立 |
| 头部复制,后备数组共享 | 使用 |
| 引用复制 | 使用 |
| 引用复制 | 同一通道 |
| 地址复制 | 同一底层值 |
| 值复制(类型+值对) | 取决于所持类型 |
Third-Party Libraries
第三方库
For advanced data structures (trees, sets, queues, stacks) beyond the standard library:
- — comprehensive collection library (trees, sets, lists, stacks, maps, queues)
emirpasic/gods - — thread-safe and non-thread-safe set implementations
deckarep/golang-set - — fast double-ended queue
gammazero/deque
When using third-party libraries, refer to their official documentation and code examples for current API signatures. Context7 can help as a discoverability platform.
对于标准库之外的高级数据结构(树、集合、队列、栈):
- ——全面的集合库(树、集合、列表、栈、映射、队列)
emirpasic/gods - ——线程安全和非线程安全的集合实现
deckarep/golang-set - ——快速双端队列
gammazero/deque
使用第三方库时,请参考其官方文档和代码示例获取当前API签名。Context7可作为发现平台提供帮助。
Cross-References
交叉引用
- → See skill for struct field alignment, memory layout optimization, and cache locality
samber/cc-skills-golang@golang-performance - → See skill for nil map/slice pitfalls, append aliasing, defensive copying,
samber/cc-skills-golang@golang-safety/slices.CloneEqual - → See skill for channels,
samber/cc-skills-golang@golang-concurrency,sync.Map, and all sync primitivessync.Pool - → See skill for
samber/cc-skills-golang@golang-design-patternsvsstringvs[]byte, iterators, streaming[]rune - → See skill for struct composition, embedding, and generics vs
samber/cc-skills-golang@golang-structs-interfacesany - → See skill for slice/map initialization style
samber/cc-skills-golang@golang-code-style
- → 关于结构体字段对齐、内存布局优化和缓存局部性,请查看技能
samber/cc-skills-golang@golang-performance - → 关于nil映射/切片陷阱、append别名、防御性复制、/
slices.Clone,请查看Equal技能samber/cc-skills-golang@golang-safety - → 关于通道、、
sync.Map及所有同步原语,请查看sync.Pool技能samber/cc-skills-golang@golang-concurrency - → 关于vs
stringvs[]byte、迭代器、流处理,请查看[]rune技能samber/cc-skills-golang@golang-design-patterns - → 关于结构体组合、嵌入、泛型vs ,请查看
any技能samber/cc-skills-golang@golang-structs-interfaces - → 关于切片/映射初始化风格,请查看技能
samber/cc-skills-golang@golang-code-style
Common Mistakes
常见错误
| Mistake | Fix |
|---|---|
| Growing a slice in a loop without preallocation | Each growth copies the entire backing array — O(n) per growth. Use |
Using | Linked lists have poor cache locality (each node is a separate heap allocation). Benchmark first |
| Buffer's |
| GC can move the object between statements — the |
| Large struct values in maps (copying overhead) | Map access copies the entire value. Use |
| 错误 | 修复方案 |
|---|---|
| 循环中增长切片但不预分配 | 每次增长都会复制整个后备数组——每次增长时间复杂度O(n)。使用 |
可用切片时却使用 | 链表的缓存局部性差(每个节点都是单独的堆分配)。请先进行基准测试 |
纯字符串构建使用 | Buffer的 |
| GC可能在语句间移动对象—— |
| 映射中存储大结构体值(复制开销) | 映射访问会复制整个值。对于大值类型,使用 |