$npx -y skills add samber/cc-skills-golang --skill golang-data-structuresGolang data structures — slices (internals, capacity growth, preallocation, slices package), maps (internals, hash buckets, maps package), arrays, container/list/heap/ring, strings.Builder vs bytes.Buffer, generic collections, pointers (unsafe.Pointer, weak.Pointer), and copy sem
| 1 | **Persona:** 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. |
| 2 | |
| 3 | # Go Data Structures |
| 4 | |
| 5 | Built-in and standard library data structures: internals, correct usage, and selection guidance. For safety pitfalls (nil maps, append aliasing, defensive copies) see `samber/cc-skills-golang@golang-safety` skill. For channels and sync primitives see `samber/cc-skills-golang@golang-concurrency` skill. For string/byte/rune choice see `samber/cc-skills-golang@golang-design-patterns` skill. |
| 6 | |
| 7 | ## Best Practices Summary |
| 8 | |
| 9 | 1. **Preallocate slices and maps** with `make(T, 0, n)` / `make(map[K]V, n)` when size is known or estimable — avoids repeated growth copies and rehashing |
| 10 | 2. **Arrays** SHOULD be preferred over slices only for fixed, compile-time-known sizes (hash digests, IPv4 addresses, matrix dimensions) |
| 11 | 3. **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 |
| 12 | 4. **Use `container/heap`** for priority queues, **`container/list`** only when frequent middle insertions are needed, **`container/ring`** for fixed-size circular buffers |
| 13 | 5. **`strings.Builder`** MUST be preferred for building strings; **`bytes.Buffer`** MUST be preferred for bidirectional I/O (implements both `io.Reader` and `io.Writer`) |
| 14 | 6. Generic data structures SHOULD use the **tightest constraint** possible — `comparable` for keys, custom interfaces for ordering |
| 15 | 7. **`unsafe.Pointer`** MUST only follow the 6 valid conversion patterns from the Go spec — NEVER store in a `uintptr` variable across statements |
| 16 | 8. **`weak.Pointer[T]`** (Go 1.24+) SHOULD be used for caches and canonicalization maps to allow GC to reclaim entries |
| 17 | |
| 18 | ## Slice Internals |
| 19 | |
| 20 | A slice is a 3-word header: pointer, length, capacity. Multiple slices can share a backing array (→ see `samber/cc-skills-golang@golang-safety` for aliasing traps and the header diagram). |
| 21 | |
| 22 | ### Capacity Growth |
| 23 | |
| 24 | - < 256 elements: capacity doubles |
| 25 | - > = 256 elements: grows by ~25% (`newcap += (newcap + 3*256) / 4`) |
| 26 | - Each growth copies the entire backing array — O(n) |
| 27 | |
| 28 | ### Preallocation |
| 29 | |
| 30 | ```go |
| 31 | // Exact size known |
| 32 | users := make([]User, 0, len(ids)) |
| 33 | |
| 34 | // Approximate size known |
| 35 | results := make([]Result, 0, estimatedCount) |
| 36 | |
| 37 | // Pre-grow before bulk append (Go 1.21+) |
| 38 | s = slices.Grow(s, additionalNeeded) |
| 39 | ``` |
| 40 | |
| 41 | ### `slices` Package (Go 1.21+) |
| 42 | |
| 43 | Key functions: `Sort`/`SortFunc`, `BinarySearch`, `Contains`, `Compact`, `Grow`. For `Clone`, `Equal`, `DeleteFunc` → see `samber/cc-skills-golang@golang-safety` skill. |
| 44 | |
| 45 | **[Slice Internals Deep Dive](./references/slice-internals.md)** — Full `slices` package reference, growth mechanics, `len` vs `cap`, header copying, backing array aliasing. |
| 46 | |
| 47 | ## Map Internals |
| 48 | |
| 49 | Maps are hash tables with 8-entry buckets and overflow chains. They are reference types — assigning a map copies the pointer, not the data. |
| 50 | |
| 51 | ### Preallocation |
| 52 | |
| 53 | ```go |
| 54 | m := make(map[string]*User, len(users)) // avoids rehashing during population |
| 55 | ``` |
| 56 | |
| 57 | ### `maps` Package Quick Reference (Go 1.21+) |
| 58 | |
| 59 | | Function | Purpose | |
| 60 | | ----------------- | ---------------------------- | |
| 61 | | `Collect` (1.23+) | Build map from iterator | |
| 62 | | `Insert` (1.23+) | Insert entries from iterator | |
| 63 | | `All` (1.23+) | Iterator over all entries | |
| 64 | | `Keys`, `Values` | Iterators over keys/values | |
| 65 | |
| 66 | For `Clone`, `Equal`, sorted iteration → see `samber/cc-skills-golang@golang-safety` skill. |
| 67 | |
| 68 | **[Map Internals Deep Dive](./references/map-internals.md)** — 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. |
| 69 | |
| 70 | ## Arrays |
| 71 | |
| 72 | Fixed-size, value types. Copied entirely on assignment. Use for compile-time-known sizes: |
| 73 | |
| 74 | ```go |
| 75 | type Digest [32]byte |