npx skills add https://github.com/samber/cc-skills-golang --skill golang-code-style社区默认值。 明确取代
samber/cc-skills-golang@golang-code-style技能的公司技能具有优先权。
需要人工判断的风格规则——格式化由 linter 处理,此技能处理清晰度。关于命名,请参阅 samber/cc-skills-golang@golang-naming 技能;关于设计模式,请参阅 samber/cc-skills-golang@golang-design-patterns 技能;关于结构体/接口设计,请参阅 samber/cc-skills-golang@golang-structs-interfaces 技能。
"清晰胜于巧妙。" — Go 箴言
当忽略某条规则时,请在代码中添加注释。
没有严格的行长度限制,但超过约 120 个字符的行必须换行。在语义边界处换行,而不是任意的列计数。包含 4 个或更多参数的函数调用必须每个参数占一行——即使提示要求单行代码:
// 良好 — 每个参数单独一行,右括号单独一行
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
handleUsers(
w,
r,
serviceName,
cfg,
logger,
authMiddleware,
)
})
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
当函数签名过长时,真正的解决方法通常是减少参数数量(使用选项结构体),而不是更好的换行。对于多行签名,将每个参数放在单独一行。
对于非零值应该使用 :=,对于零值初始化使用 var。这种形式表明了意图:var 意味着"这个变量从零开始"。
var count int // 零值,稍后设置
name := "default" // 非零值,:= 是合适的
var buf bytes.Buffer // 零值即可使用
切片和映射必须显式初始化,永远不要为 nil。nil 映射在写入时会 panic;nil 切片在 JSON 中序列化为 null(而空切片为 []),这会令 API 使用者感到意外。
users := []User{} // 总是初始化
m := map[string]int{} // 总是初始化
users := make([]User, 0, len(ids)) // 当容量已知时预分配
m := make(map[string]int, len(items)) // 当大小已知时预分配
不要进行推测性预分配——当常见情况是 10 个元素时,make([]T, 0, 1000) 会浪费内存。
复合字面量必须使用字段名——当类型添加或重新排序字段时,位置字段会出错:
srv := &http.Server{
Addr: ":8080",
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
错误和边界情况必须首先处理(提前返回)。保持主路径在最小缩进级别:
func process(data []byte) (*Result, error) {
if len(data) == 0 {
return nil, errors.New("empty data")
}
parsed, err := parse(data)
if err != nil {
return nil, fmt.Errorf("parsing: %w", err)
}
return transform(parsed), nil
}
else当 if 主体以 return/break/continue 结束时,必须省略 else。对于简单的赋值,使用默认值然后覆盖的方式——分配一个默认值,然后用独立的条件或 switch 覆盖:
// 良好 — 使用 switch 进行默认值然后覆盖(对于互斥的覆盖最清晰)
level := slog.LevelInfo
switch {
case debug:
level = slog.LevelDebug
case verbose:
level = slog.LevelWarn
}
// 不佳 — else-if 链隐藏了存在默认值的事实
if debug {
level = slog.LevelDebug
} else if verbose {
level = slog.LevelWarn
} else {
level = slog.LevelInfo
}
当 if 条件有 3 个或更多操作数时,必须提取为命名的布尔变量——一长串 || 难以阅读且隐藏了业务逻辑。将昂贵的检查保持在内联以利用短路求值的好处。详情
// 良好 — 命名的布尔变量使意图清晰
isAdmin := user.Role == RoleAdmin
isOwner := resource.OwnerID == user.ID
isPublicVerified := resource.IsPublic && user.IsVerified
if isAdmin || isOwner || isPublicVerified || permissions.Contains(PermOverride) {
allow()
}
当变量仅用于检查时,将其作用域限定在 if 块内:
if err := validate(input); err != nil {
return err
}
当多次比较同一个变量时,优先使用 switch:
switch status {
case StatusActive:
activate()
case StatusInactive:
deactivate()
default:
panic(fmt.Sprintf("unexpected status: %d", status))
}
samber/cc-skills-golang@golang-design-patterns 技能)。context.Context,然后是输入,最后是输出目标。func FetchUser(ctx context.Context, id string) (*User, error)
func SendEmail(ctx context.Context, msg EmailMessage) error // 分组到结构体中
range 进行迭代应该使用 range 而不是基于索引的循环。使用 range n (Go 1.22+) 进行简单的计数。
for _, user := range users {
process(user)
}
小类型(string、int、bool、time.Time)按值传递。当需要修改、对于大型结构体(约 128+ 字节)或当 nil 有意义时,使用指针。详情
_ "pkg") 注册副作用(init 函数)。将它们限制在 main 和测试包中,可以使副作用在应用程序根目录可见,而不是隐藏在库代码中使用 strconv 进行简单转换(更快),使用 fmt.Sprintf 进行复杂格式化。在错误消息中使用 %q 使字符串边界可见。在循环中使用 strings.Builder,对于简单连接使用 +。
优先使用显式的、窄范围的转换。当具体类型可行时,使用泛型而不是 any:
func Contains[T comparable](slice []T, target T) bool // 而不是 []any
slices 和 maps 标准包;对于过滤/分组/分块,使用 github.com/samber/loreflect当审查大型代码库的代码风格时,使用最多 5 个并行子代理(通过 Agent 工具),每个代理针对一个独立的风格关注点(例如,控制流、函数设计、变量声明、字符串处理、代码组织)。
许多规则是自动强制执行的:gofmt、gofumpt、goimports、gocritic、revive、wsl_v5。→ 参见 samber/cc-skills-golang@golang-linter 技能。
samber/cc-skills-golang@golang-naming 技能samber/cc-skills-golang@golang-structs-interfaces 技能samber/cc-skills-golang@golang-design-patterns 技能samber/cc-skills-golang@golang-linter 技能每周安装量
104
仓库
GitHub 星标数
184
首次出现
3 天前
安全审计
安装于
opencode84
gemini-cli83
cursor83
codex83
github-copilot82
kimi-cli82
Community default. A company skill that explicitly supersedes
samber/cc-skills-golang@golang-code-styleskill takes precedence.
Style rules that require human judgment — linters handle formatting, this skill handles clarity. For naming see samber/cc-skills-golang@golang-naming skill; for design patterns see samber/cc-skills-golang@golang-design-patterns skill; for struct/interface design see samber/cc-skills-golang@golang-structs-interfaces skill.
"Clear is better than clever." — Go Proverbs
When ignoring a rule, add a comment to the code.
No rigid line limit, but lines beyond ~120 characters MUST be broken. Break at semantic boundaries , not arbitrary column counts. Function calls with 4+ arguments MUST use one argument per line — even when the prompt asks for single-line code:
// Good — each argument on its own line, closing paren separate
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
handleUsers(
w,
r,
serviceName,
cfg,
logger,
authMiddleware,
)
})
When a function signature is too long, the real fix is often fewer parameters (use an options struct) rather than better line wrapping. For multi-line signatures, put each parameter on its own line.
SHOULD use := for non-zero values, var for zero-value initialization. The form signals intent: var means "this starts at zero."
var count int // zero value, set later
name := "default" // non-zero, := is appropriate
var buf bytes.Buffer // zero value is ready to use
Slices and maps MUST be initialized explicitly, never nil. Nil maps panic on write; nil slices serialize to null in JSON (vs [] for empty slices), surprising API consumers.
users := []User{} // always initialized
m := map[string]int{} // always initialized
users := make([]User, 0, len(ids)) // preallocate when capacity is known
m := make(map[string]int, len(items)) // preallocate when size is known
Do not preallocate speculatively — make([]T, 0, 1000) wastes memory when the common case is 10 items.
Composite literals MUST use field names — positional fields break when the type adds or reorders fields:
srv := &http.Server{
Addr: ":8080",
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
Errors and edge cases MUST be handled first (early return). Keep the happy path at minimal indentation:
func process(data []byte) (*Result, error) {
if len(data) == 0 {
return nil, errors.New("empty data")
}
parsed, err := parse(data)
if err != nil {
return nil, fmt.Errorf("parsing: %w", err)
}
return transform(parsed), nil
}
elseWhen the if body ends with return/break/continue, the else MUST be dropped. Use default-then-override for simple assignments — assign a default, then override with independent conditions or a switch:
// Good — default-then-override with switch (cleanest for mutually exclusive overrides)
level := slog.LevelInfo
switch {
case debug:
level = slog.LevelDebug
case verbose:
level = slog.LevelWarn
}
// Bad — else-if chain hides that there's a default
if debug {
level = slog.LevelDebug
} else if verbose {
level = slog.LevelWarn
} else {
level = slog.LevelInfo
}
When an if condition has 3+ operands, MUST extract into named booleans — a wall of || is unreadable and hides business logic. Keep expensive checks inline for short-circuit benefit. Details
// Good — named booleans make intent clear
isAdmin := user.Role == RoleAdmin
isOwner := resource.OwnerID == user.ID
isPublicVerified := resource.IsPublic && user.IsVerified
if isAdmin || isOwner || isPublicVerified || permissions.Contains(PermOverride) {
allow()
}
Scope variables to if blocks when only needed for the check:
if err := validate(input); err != nil {
return err
}
When comparing the same variable multiple times, prefer switch:
switch status {
case StatusActive:
activate()
case StatusInactive:
deactivate()
default:
panic(fmt.Sprintf("unexpected status: %d", status))
}
Functions SHOULD be short and focused — one function, one job.
Functions SHOULD have ≤4 parameters. Beyond that, use an options struct (see samber/cc-skills-golang@golang-design-patterns skill).
Parameter order : context.Context first, then inputs, then output destinations.
Naked returns help in very short functions (1-3 lines) where return values are obvious, but become confusing when readers must scroll to find what's returned — name returns explicitly in longer functions.
func FetchUser(ctx context.Context, id string) (*User, error) func SendEmail(ctx context.Context, msg EmailMessage) error // grouped into struct
range for IterationSHOULD use range over index-based loops. Use range n (Go 1.22+) for simple counting.
for _, user := range users {
process(user)
}
Pass small types (string, int, bool, time.Time) by value. Use pointers when mutating, for large structs (~128+ bytes), or when nil is meaningful. Details
_ "pkg") register side effects (init functions). Restricting them to main and test packages makes side effects visible at the application root, not hidden in library codeUse strconv for simple conversions (faster), fmt.Sprintf for complex formatting. Use %q in error messages to make string boundaries visible. Use strings.Builder for loops, + for simple concatenation.
Prefer explicit, narrow conversions. Use generics over any when a concrete type will do:
func Contains[T comparable](slice []T, target T) bool // not []any
slices and maps standard packages; for filter/group-by/chunk, use github.com/samber/loreflect unless necessaryWhen reviewing code style across a large codebase, use up to 5 parallel sub-agents (via the Agent tool), each targeting an independent style concern (e.g. control flow, function design, variable declarations, string handling, code organization).
Many rules are enforced automatically: gofmt, gofumpt, goimports, gocritic, revive, wsl_v5. → See the samber/cc-skills-golang@golang-linter skill.
samber/cc-skills-golang@golang-naming skill for identifier naming conventionssamber/cc-skills-golang@golang-structs-interfaces skill for pointer vs value receivers, interface designsamber/cc-skills-golang@golang-design-patterns skill for functional options, builders, constructorssamber/cc-skills-golang@golang-linter skill for automated formatting enforcementWeekly Installs
104
Repository
GitHub Stars
184
First Seen
3 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode84
gemini-cli83
cursor83
codex83
github-copilot82
kimi-cli82
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
116,600 周安装
UnoCSS 原子化 CSS 引擎教程 - 即时、灵活、Tailwind 超集,前端开发必备
218 周安装
宏观状态检测器:使用跨资产比率分析识别结构性市场状态转换 | 投资组合配置工具
225 周安装
党政机关公文写作指南:GB/T 9704-2012格式规范、模板与质量检查
224 周安装
AI SDK 提供商包开发指南:如何创建 @ai-sdk/<provider> 集成包
220 周安装
Java性能优化指南:JVM调优、GC优化、内存分析与基准测试
220 周安装
Tailwind CSS & shadcn/ui 设计系统构建指南:从设计令牌到组件库
221 周安装