Which of Go's built-in containers to reach for — a slice, a map, a heap, a ring buffer — and what each one really costs in memory and copying.
WHEN TO USE
SCOPE
USE FOR
Preallocate a slice or map with make when the final size is already known.
Decide between container/list, container/heap, and container/ring for a specific job.
Pick strings.Builder over bytes.Buffer for pure string concatenation.
Write a generic collection type using the tightest constraint the case allows.
Use weak.Pointer for a cache that shouldn't stop the garbage collector from reclaiming entries.
NOT FOR
Not for applying optimization patterns once profiling has already found a bottleneck.
This is a saved copy of the skill's SKILL.md instructions. It may differ from the upstream file or the version you install.
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.
Go Data Structures
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.
Best Practices Summary
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
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 container/heap for priority queues, container/list only when frequent middle insertions are needed, container/ring for fixed-size circular buffers
strings.Builder MUST be preferred for building strings; bytes.Buffer MUST be preferred for bidirectional I/O (implements both io.Reader and io.Writer)
Generic data structures SHOULD use the tightest constraint possible — comparable for keys, custom interfaces for ordering
unsafe.Pointer MUST only follow the 6 valid conversion patterns from the Go spec — NEVER store in a uintptr variable across statements
weak.Pointer[T] (Go 1.24+) SHOULD be used for caches and canonicalization maps to allow GC to reclaim entries
Slice Internals
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).
Each growth copies the entire backing array — O(n)
Preallocation
// 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)
slices Package (Go 1.21+)
Key functions: Sort/SortFunc, BinarySearch, Contains, Compact, Grow. For Clone, Equal, DeleteFunc → see samber/cc-skills-golang@golang-safety skill.
Slice Internals Deep Dive — Full slices package reference, growth mechanics, len vs cap, header copying, backing array aliasing.
Map 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.
Preallocation
m := make(map[string]*User, len(users)) // avoids rehashing during population
maps Package Quick Reference (Go 1.21+)
Function
Purpose
Collect (1.23+)
Build map from iterator
Insert (1.23+)
Insert entries from iterator
All (1.23+)
Iterator over all entries
Keys, Values
Iterators over keys/values
For Clone, Equal, sorted iteration → see samber/cc-skills-golang@golang-safety skill.
Map 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.
Arrays
Fixed-size, value types. Copied entirely on assignment. Use for compile-time-known sizes:
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 keys
Prefer slices for everything else — arrays cannot grow and pass by value (expensive for large sizes).
container/ Standard Library
Package
Data Structure
Best For
container/list
Doubly-linked list
LRU caches, frequent middle insertion/removal
container/heap
Min-heap (priority queue)
Top-K, scheduling, Dijkstra
container/ring
Circular buffer
Rolling windows, round-robin
bufio
Buffered reader/writer/scanner
Efficient I/O with small reads/writes
Container types use any (no type safety) — consider generic wrappers. Container Patterns, bufio, and Examples — When to use each container type, generic wrappers to add type safety, and bufio patterns for efficient I/O.
strings.Builder vs bytes.Buffer
Use strings.Builder for pure string concatenation (avoids copy on String()), bytes.Buffer when you need io.Reader or byte manipulation. Both support Grow(n). Details and comparison
Generic Collections (Go 1.18+)
Use the tightest constraint possible. comparable for map keys, cmp.Ordered for sorting, custom interfaces for domain-specific ordering.
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.
Pointer Types Deep Dive — Normal pointers, unsafe.Pointer (the 6 valid spec patterns), and weak.Pointer[T] for GC-safe caches that don't prevent cleanup.
Copy Semantics Quick Reference
Type
Copy Behavior
Independence
int, float, bool, string
Value (deep copy)
Fully independent
array, struct
Value (deep copy)
Fully independent
slice
Header copied, backing array shared
Use slices.Clone
map
Reference copied
Use maps.Clone
channel
Reference copied
Same channel
*T (pointer)
Address copied
Same underlying value
interface
Value copied (type + value pair)
Depends on held type
Third-Party Libraries
For advanced data structures (trees, sets, queues, stacks) beyond the standard library:
deckarep/golang-set — thread-safe and non-thread-safe set implementations
gammazero/deque — fast double-ended queue
When using third-party libraries, refer to their official documentation and code examples for current API signatures.
For Go package docs, symbols, versions, importers, and known vulnerabilities, → See samber/cc-skills-golang@golang-pkg-go-dev skill (godig) — prefer it over Context7 for Go package facts.
To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See samber/cc-skills-golang@golang-gopls skill (gopls).
Context7 remains a fallback for docs not indexed on pkg.go.dev.
Cross-References
→ See samber/cc-skills-golang@golang-performance skill for struct field alignment, memory layout optimization, and cache locality
→ See samber/cc-skills-golang@golang-safety skill for nil map/slice pitfalls, append aliasing, defensive copying, slices.Clone/Equal
→ See samber/cc-skills-golang@golang-concurrency skill for channels, sync.Map, sync.Pool, and all sync primitives
→ See samber/cc-skills-golang@golang-design-patterns skill for string vs []byte vs []rune, iterators, streaming
→ See samber/cc-skills-golang@golang-structs-interfaces skill for struct composition, embedding, and generics vs any
→ See samber/cc-skills-golang@golang-code-style skill for slice/map initialization 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 make([]T, 0, n) or slices.Grow
Using container/list when a slice would suffice
Linked lists have poor cache locality (each node is a separate heap allocation). Benchmark first
bytes.Buffer for pure string building
Buffer's String() copies the underlying bytes. strings.Builder avoids this copy
unsafe.Pointer stored as uintptr across statements
GC can move the object between statements — the uintptr becomes a dangling reference
Large struct values in maps (copying overhead)
Map access copies the entire value. Use map[K]*V for large value types to avoid the copy
Run this outside your AI tool, using Node.js 22.20.0 or newer. Skills CLI 1.7.2 skips skill selection; prompts cancel installation without an interactive terminal. If choosing Project when asked about installation scope, open your project's folder before running this.
Install checklist
Check selected tools if a picker appears; Claude Code may be unchecked under Additional agents. ↑/↓ moves, Space toggles selections, Enter confirms.
Without a tool picker, check Installing to: for your intended tool. Stop if it names a different tool.
If asked, choose Symlink (Recommended) for shared files or Copy to all agents for separate copies; review the summary before confirming installation.
Install the find-skills skill? defaults to Yes, adding another skill for all projects. Choose No if you don't want that extra installation.
Skills CLI 1.7.2 sends install data to skills.sh by default, including the source, skill names, target tools and file details; GitHub sources are reported only when GitHub confirms the repository is public, while other remote sources can also be reported. Confirmed-public GitHub sources also trigger a security-audit request. Before installing, set the environment variable DO_NOT_TRACK=1 or DISABLE_TELEMETRY=1 to disable both.
After installing for Claude Code, open it in the installation project if you chose Project; Global makes the skill available across projects on this computer. Once Claude Code loads the skill, its description helps Claude decide when to use it.
If installation created a top-level skills folder that did not exist when your Claude Code session started, run /reload-skills in that session. Run it again after later changes in that folder.
Install the whole plugin
This route installs the Samber Golang Skills plugin package selected for your AI tool.
Add Samuel's marketplace, then install the plugin
Type both lines inside a Claude Code session, not at your shell prompt. The marketplace is a separate repository of Samuel Berthe's, samber/cc, which also lists his other plugins. The second line opens the details of cc-skills-golang, which carries this repository's 46 Go skills; pick one of the install options shown and Claude Code installs it.
01
/plugin marketplace add samber/cc
02
/plugin install cc-skills-golang@samber
Run it in your terminal. It copies the whole repository, with its 46 skills, into ~/.openclaw/skills/cc-skills-golang, OpenClaw's skills folder in your home folder. To install it for one OpenClaw workspace instead, Samuel gives ~/.openclaw/workspace/skills/cc-skills-golang as the folder.
Run it in your terminal, not inside Gemini CLI; installing from GitHub needs git on your computer. It installs the repository, with its 46 skills, as a Gemini CLI extension. To update it later, run gemini extensions update cc-skills-golang.
Run it in your terminal. It copies the whole repository, with its 46 skills, into ~/.cursor/skills/cc-skills-golang, Cursor's skills folder in your home folder.
Type it in an interactive GitHub Copilot CLI session, not at your shell prompt. It installs the repository straight from GitHub as a plugin, with its 46 skills and no marketplace to add first.
Golang benchmarking, profiling, and performance measurement. Use when writing, running, or comparing Go benchmarks, profiling hot paths with pprof, interpreting CPU/memory/trace profiles, analyzing results with benchstat, setting up CI benchmark regression detection, or investigating production performance with Prometheus runtime metrics. Also use when the developer needs deep analysis on a specific performance indicator - this skill provides the measurement methodology, while samber/cc-skills-golang@golang-performance provides the optimization patterns.Read full description
Golang CLI application development. Use when building, modifying, or reviewing a Go CLI tool — especially for command structure, flag handling, configuration layering, version embedding, exit codes, I/O patterns, signal handling, shell completion, argument validation, and CLI unit testing. Also triggers when code uses cobra, viper, or urfave/cli. For cobra-specific APIs → See samber/cc-skills-golang@golang-spf13-cobra skill; for viper configuration layering → See samber/cc-skills-golang@golang-spf13-viper skill.Read full description
Golang code style conventions — line length and breaking, variable declarations, control flow clarity, when comments help vs hurt. Use when writing or reviewing Go code, asking about style or clarity, or establishing project coding standards. Not for naming conventions (→ See samber/cc-skills-golang@golang-naming skill), linter configuration (→ See samber/cc-skills-golang@golang-lint skill), or doc comments (→ See samber/cc-skills-golang@golang-documentation skill).Read full description
Golang concurrency patterns. Use when writing or reviewing concurrent Go code involving goroutines, channels, select, locks, sync primitives, errgroup, singleflight, worker pools, or fan-out/fan-in pipelines. Also triggers when you detect goroutine leaks, race conditions, channel ownership issues, or need to choose between channels and mutexes.Read full description
Idiomatic context.Context usage in Golang — propagation through API boundaries, cancellation, timeouts and deadlines, request-scoped values, context.WithoutCancel for background work outliving requests. Apply when designing context propagation across layers, debugging leaked or unexpired contexts, choosing between context.Background/TODO/WithoutCancel, or storing values in context. Not for code that merely accepts ctx as first parameter.Read full description
CI/CD pipeline configuration using GitHub Actions for Golang projects — testing, linting, SAST, security scanning, code coverage, Dependabot, Renovate, GoReleaser, code review automation, and release pipelines. Use when setting up or improving Go project CI, configuring GitHub Actions workflows, adding linters or security scanners, automating dependency updates, or adding quality gates.Read full description