Everything-claude-code golang-patterns
install
source · Clone the upstream repo
git clone https://github.com/affaan-m/everything-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/affaan-m/everything-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.kiro/skills/golang-patterns" ~/.claude/skills/affaan-m-everything-claude-code-golang-patterns && rm -rf "$T"
manifest:
.kiro/skills/golang-patterns/SKILL.mdsource content
Go Patterns
This skill provides comprehensive Go patterns extending common design principles with Go-specific idioms.
Functional Options
Use the functional options pattern for flexible constructor configuration:
type Option func(*Server) func WithPort(port int) Option { return func(s *Server) { s.port = port } } func NewServer(opts ...Option) *Server { s := &Server{port: 8080} for _, opt := range opts { opt(s) } return s }
Benefits:
- Backward compatible API evolution
- Optional parameters with defaults
- Self-documenting configuration
Small Interfaces
Define interfaces where they are used, not where they are implemented.
Principle: Accept interfaces, return structs
// Good: Small, focused interface defined at point of use type UserStore interface { GetUser(id string) (*User, error) } func ProcessUser(store UserStore, id string) error { user, err := store.GetUser(id) // ... }
Benefits:
- Easier testing and mocking
- Loose coupling
- Clear dependencies
Dependency Injection
Use constructor functions to inject dependencies:
func NewUserService(repo UserRepository, logger Logger) *UserService { return &UserService{ repo: repo, logger: logger, } }
Pattern:
- Constructor functions (New* prefix)
- Explicit dependencies as parameters
- Return concrete types
- Validate dependencies in constructor
Concurrency Patterns
Worker Pool
func workerPool(jobs <-chan Job, results chan<- Result, workers int) { var wg sync.WaitGroup for i := 0; i < workers; i++ { wg.Add(1) go func() { defer wg.Done() for job := range jobs { results <- processJob(job) } }() } wg.Wait() close(results) }
Context Propagation
Always pass context as first parameter:
func FetchUser(ctx context.Context, id string) (*User, error) { // Check context cancellation select { case <-ctx.Done(): return nil, ctx.Err() default: } // ... fetch logic }
Error Handling
Error Wrapping
if err != nil { return fmt.Errorf("failed to fetch user %s: %w", id, err) }
Custom Errors
type ValidationError struct { Field string Msg string } func (e *ValidationError) Error() string { return fmt.Sprintf("%s: %s", e.Field, e.Msg) }
Sentinel Errors
var ( ErrNotFound = errors.New("not found") ErrInvalid = errors.New("invalid input") ) // Check with errors.Is if errors.Is(err, ErrNotFound) { // handle not found }
Package Organization
Structure
project/ ├── cmd/ # Main applications │ └── server/ │ └── main.go ├── internal/ # Private application code │ ├── domain/ # Business logic │ ├── handler/ # HTTP handlers │ └── repository/ # Data access └── pkg/ # Public libraries
Naming Conventions
- Package names: lowercase, single word
- Avoid stutter:
notuser.Useruser.UserModel - Use
for private codeinternal/ - Keep
package minimalmain
Testing Patterns
Table-Driven Tests
func TestValidate(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"valid", "test@example.com", false}, {"invalid", "not-an-email", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := Validate(tt.input) if (err != nil) != tt.wantErr { t.Errorf("got error %v, wantErr %v", err, tt.wantErr) } }) } }
Test Helpers
func testDB(t *testing.T) *sql.DB { t.Helper() db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatalf("failed to open test db: %v", err) } t.Cleanup(func() { db.Close() }) return db }
When to Use This Skill
- Designing Go APIs and packages
- Implementing concurrent systems
- Structuring Go projects
- Writing idiomatic Go code
- Refactoring Go codebases