<< All versions

Skill v1.0.0

currentAutomated scan100/100
taoidle/plan-cascade/go
──Details
PublishedNovember 5, 2026 at 11:41 AM
Content Hashsha256:30a17c4639fe7863...
Git SHAa264eeed757e
──Files
Files (1 file, 2.1 KB)
SKILL.md2.1 KBactive
SKILL.md · 96 lines · 2.1 KB

name: go-best-practices description: Go coding best practices. Use when writing or reviewing Go code. Covers error handling, concurrency, and idiomatic patterns. license: MIT metadata: author: plan-cascade version: "1.0.0"


Go Best Practices

Code Style

RuleGuideline
Formattergofmt or goimports
Lintergolangci-lint
NamingShort, clear; avoid stuttering
CommentsGodoc for exported items

Error Handling

RuleGuideline
Always checkNever ignore errors
Wrap contextfmt.Errorf("ctx: %w", err)
Sentinel errorsvar ErrNotFound = errors.New(...)
go
func Load(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("load config %s: %w", path, err)
}
// ...
}

Project Structure

cmd/appname/main.go
internal/config/
internal/service/
go.mod

Concurrency

PatternUsage
context.ContextCancellation, timeouts
sync.WaitGroupWait for goroutines
errgroup.GroupGoroutines with errors
go
func Process(ctx context.Context, items []Item) error {
for _, item := range items {
select {
case <-ctx.Done():
return ctx.Err()
default:
if err := process(item); err != nil { return err }
}
}
return nil
}

Anti-Patterns

AvoidUse Instead
Naked returnsExplicit returns
panic for errorsReturn errors
Large interfacesSmall, focused
init()Explicit init

Testing (Table-Driven)

go
func TestParse(t *testing.T) {
tests := []struct{ name, input string; want int; wantErr bool }{
{"valid", "42", 42, false},
{"invalid", "abc", 0, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Parse(tt.input)
if (err != nil) != tt.wantErr { t.Errorf("err=%v, want=%v", err, tt.wantErr) }
if got != tt.want { t.Errorf("got=%v, want=%v", got, tt.want) }
})
}
}
All versions