关于
This skill provides best practices for Go's core data structures: slices, maps, and arrays, covering common pitfalls like nil vs. empty slices, aliasing, preallocation, and map iteration. Use it for questions about slice semantics, implementing sets, or choosing between data structures. It explicitly excludes concurrency, performance profiling, and generic design topics, which are covered by other skills.
快速安装
Claude Code
推荐npx skills add eduardo-sl/go-agent-skills -a claude-code/plugin add https://github.com/eduardo-sl/go-agent-skillsgit clone https://github.com/eduardo-sl/go-agent-skills.git ~/.claude/skills/go-data-structures在 Claude Code 中复制并粘贴此命令以安装该技能
技能文档
Go Data Structures
Slices and maps look simple and hide the sharpest edges in the language. These rules prevent the aliasing, nil, and iteration bugs that survive code review.
1. Nil Slice vs Empty Slice
var a []int // nil slice — len 0, cap 0, no allocation
b := []int{} // empty slice — len 0, allocated header
c := make([]int, 0) // empty slice — same as b
len,cap,range, andappendtreat all three identically.- Prefer the nil slice as the "no elements" value; don't allocate just to return "empty".
- Exception: JSON.
nilmarshals tonull, empty marshals to[]. If the API contract requires[], return an empty slice explicitly. - Never distinguish nil from empty in logic — check
len(s) == 0.
2. Append Semantics and Aliasing
append MAY return the same backing array or a new one. Both cases
bite:
// ❌ Bad — result may alias the input
func addSuffix(base []string) []string {
return append(base, "suffix") // if cap(base) > len(base),
} // this WRITES INTO base's array
// ✅ Good — force a copy when the input must not be touched
func addSuffix(base []string) []string {
out := make([]string, len(base), len(base)+1)
copy(out, base)
return append(out, "suffix")
}
// ❌ Bad — subslice keeps the whole 64 MB alive
func header(big []byte) []byte {
return big[:512] // backing array is still the full big
}
// ✅ Good — copy the window you keep
func header(big []byte) []byte {
return slices.Clone(big[:512]) // Go 1.21+; or copy() manually
}
Rule: a function either owns a slice or copies it. Returning a subslice of a caller's slice, or appending to one, silently shares memory.
3. Preallocation
When the final size is known or bounded, allocate once:
// ✅ Good — one allocation
names := make([]string, 0, len(users))
for _, u := range users {
names = append(names, u.Name)
}
// ❌ Bad — repeated growth and copying
var names []string
for _, u := range users {
names = append(names, u.Name)
}
Same for maps: make(map[string]int, len(items)).
Don't preallocate when the size is unknown — a wrong large cap wastes
memory; append growth is fine for cold paths.
4. Map Essentials
// Comma-ok distinguishes "missing" from "zero value"
count, ok := hits[key]
if !ok { /* key absent */ }
// Zero value reads are safe; writes to a nil map PANIC
var m map[string]int
_ = m["x"] // 0, fine
m["x"] = 1 // panic: assignment to entry in nil map — make() first
// Iteration order is RANDOM and differs between runs.
// Sort keys when output must be deterministic:
keys := slices.Sorted(maps.Keys(m)) // Go 1.23+
for _, k := range keys {
fmt.Println(k, m[k])
}
- Map values are not addressable:
m[k].Field = vdoesn't compile for struct values. Use a map of pointers, or read-modify-write. - Deleting during
rangeis safe; inserting duringrangeis unspecified (the new key may or may not be visited).
5. Sets
The idiomatic set is a map with empty-struct values:
seen := make(map[string]struct{}, len(items))
for _, it := range items {
if _, dup := seen[it.ID]; dup {
continue
}
seen[it.ID] = struct{}{}
process(it)
}
struct{} occupies zero bytes; map[string]bool also works and reads
better when you'll test membership with if seen[id].
6. Arrays vs Slices
- Arrays (
[4]byte) are values: assignment and passing copy the whole array. Comparable with==when elements are comparable. - Use arrays for fixed-size data with value semantics: hashes
(
[32]byte), IPv4 addresses, fixed matrices, map keys. - Everything else is a slice. A function taking
[100]intcopies 800 bytes per call — almost always wrong.
7. Choosing a Structure
| Need | Use |
|---|---|
| Ordered collection, growable | []T |
| Membership / dedup | map[K]struct{} |
| Key→value lookup | map[K]V |
| Fixed size, value semantics, comparable | [N]T array |
| FIFO queue (single goroutine) | slice with head index, or container/list for heavy churn |
| Stack | slice + append / s[:len(s)-1] |
| Concurrent map, write-once read-many keys | sync.Map — otherwise mutex + map |
sync.Map is a special-case tool (append-only caches, disjoint key
sets). Default to map + sync.RWMutex; see the concurrency skill for
locking patterns.
Verification Checklist
- No logic distinguishes nil slice from empty slice;
len()used for emptiness - JSON-facing slices explicitly empty (not nil) where the contract requires
[] - No
appendto a slice the function doesn't own; copies made explicit - No long-lived subslices of large arrays without
slices.Clone/copy - Slices and maps preallocated with capacity when size is known
- Comma-ok used wherever "missing" differs from zero value
- No writes to possibly-nil maps
- Deterministic output paths sort map keys before iteration
- Sets built as
map[K]struct{}(ormap[K]boolfor readability) - Arrays only where value semantics or comparability is the point
GitHub 仓库
常见问题
什么是 go-data-structures Skill?
go-data-structures 是一个 Claude Skill,作者为 eduardo-sl。Skill 将 Claude 按需加载的说明和资源打包,让 Claude 无需额外提示即可执行与 go-data-structures 相关的任务。
如何安装 go-data-structures?
使用本页的安装命令:将 go-data-structures 作为插件添加到 Claude Code,或将其仓库克隆到 skills 目录,然后重启 Claude 以加载该 Skill。
go-data-structures 属于哪个分类?
go-data-structures 属于设计分类。
go-data-structures 可以免费使用吗?
可以。go-data-structures 已收录在 AIMCP,可免费安装。
相关推荐技能
该Skill用于当开发者提供完整实施计划时,以受控批次方式执行代码实现。它会先审阅计划并提出疑问,然后分批次执行任务(默认每批3个任务),并在批次间暂停等待审查。关键特性包括分批次执行、内置检查点和架构师审查机制,确保复杂系统实现的可控性。
该Skill可在完成任务、实现主要功能或合并代码前自动调度代码审查子代理,确保实现符合需求和计划。它支持通过指定git SHA范围进行精准的代码变更审查,帮助开发者在关键节点及时发现潜在问题。核心原则是"早审查、勤审查",适用于开发流程的各个关键阶段。
这个Skill指导开发者如何将MCP服务器连接到Claude Code,支持HTTP、stdio和SSE三种传输协议。它涵盖了从安装配置到认证安全的完整流程,适用于集成GitHub、Notion、数据库等外部服务。当开发者需要添加集成、配置外部工具或提及MCP相关功能时,这个Skill能提供实用的操作指南。
该Skill帮助开发者根据任务特性选择Claude Code的Web或CLI界面,并指导如何在两种环境间无缝迁移会话。它能分析任务复杂度、迭代需求等要素,推荐最优工作界面和工作流。关键特性包括会话状态管理、环境切换指导和上下文优化建议。
