[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71N1Z3SWJZBHY26FXSMZRAS":3,"skill-same:01M71N1Z3SWJZBHY26FXSMZRAS":86},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":15,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":58,"commitSha":59,"skillDirectory":60,"forksCount":61,"repositoryHtmlUrl":62,"repositoryHomepageUrl":63,"ownerHtmlUrl":64,"ownerBlogUrl":65,"ownerDescription":6,"updatedAt":66,"install":67,"resources":80},"01M71N1Z3SWJZBHY26FXSMZRAS","golang-patterns",null,"Use when writing, reviewing or refactoring Go code for idiomatic structure: error wrapping, small interfaces, goroutine coordination and package design.","monoes\u002Fmonomind","monoes","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F276744696?v=4","01M71KWF37AJ2NJBP3KWBVSDGT","01M71KWF4CSF8ADH0M6HA09VD2",23,"MIT","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fgolang-patterns\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fgolang-patterns\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"patterns","golang","golang patterns","package","for","coding-standards","idiomatic","standards","context","coding","go","refactoring","structure","coordination","code","query","when","writing","design","error","2026-11-10 10:56:23",false,"---\nname: golang-patterns\ndescription: \"Use when writing, reviewing or refactoring Go code for idiomatic structure: error wrapping, small interfaces, goroutine coordination and package design.\"\ntags: [\"engineering\",\"backend\",\"go\",\"coding-standards\"]\ntools: [\"monograph_query\",\"monograph_context\"]\nlicense: MIT\nsource: https:\u002F\u002Fgithub.com\u002Faffaan-m\u002FECC\nsource_path: \"skills\u002Fgolang-patterns\"\nsource_commit: bf70150eb2df8070024e5bdf08e4aa08959e2735\n---\n# Go Development Patterns\n\nIdiomatic Go patterns and best practices for building robust, efficient, and maintainable applications.\n\n## When to Activate\n\n- Writing new Go code\n- Reviewing Go code\n- Refactoring existing Go code\n- Designing Go packages\u002Fmodules\n\n## Core Principles\n\n### 1. Simplicity and Clarity\n\nGo favors simplicity over cleverness. Code should be obvious and easy to read.\n\n```go\n\u002F\u002F Good: Clear and direct\nfunc GetUser(id string) (*User, error) {\n    user, err := db.FindUser(id)\n    if err != nil {\n        return nil, fmt.Errorf(\"get user %s: %w\", id, err)\n    }\n    return user, nil\n}\n\n\u002F\u002F Bad: Overly clever\nfunc GetUser(id string) (*User, error) {\n    return func() (*User, error) {\n        if u, e := db.FindUser(id); e == nil {\n            return u, nil\n        } else {\n            return nil, e\n        }\n    }()\n}\n```\n\n### 2. Make the Zero Value Useful\n\nDesign types so their zero value is immediately usable without initialization.\n\n```go\n\u002F\u002F Good: Zero value is useful\ntype Counter struct {\n    mu    sync.Mutex\n    count int \u002F\u002F zero value is 0, ready to use\n}\n\nfunc (c *Counter) Inc() {\n    c.mu.Lock()\n    c.count++\n    c.mu.Unlock()\n}\n\n\u002F\u002F Good: bytes.Buffer works with zero value\nvar buf bytes.Buffer\nbuf.WriteString(\"hello\")\n\n\u002F\u002F Bad: Requires initialization\ntype BadCounter struct {\n    counts map[string]int \u002F\u002F nil map will panic\n}\n```\n\n### 3. Accept Interfaces, Return Structs\n\nFunctions should accept interface parameters and return concrete types.\n\n```go\n\u002F\u002F Good: Accepts interface, returns concrete type\nfunc ProcessData(r io.Reader) (*Result, error) {\n    data, err := io.ReadAll(r)\n    if err != nil {\n        return nil, err\n    }\n    return &Result{Data: data}, nil\n}\n\n\u002F\u002F Bad: Returns interface (hides implementation details unnecessarily)\nfunc ProcessData(r io.Reader) (io.Reader, error) {\n    \u002F\u002F ...\n}\n```\n\n## Error Handling Patterns\n\n### Error Wrapping with Context\n\n```go\n\u002F\u002F Good: Wrap errors with context\nfunc LoadConfig(path string) (*Config, error) {\n    data, err := os.ReadFile(path)\n    if err != nil {\n        return nil, fmt.Errorf(\"load config %s: %w\", path, err)\n    }\n\n    var cfg Config\n    if err := json.Unmarshal(data, &cfg); err != nil {\n        return nil, fmt.Errorf(\"parse config %s: %w\", path, err)\n    }\n\n    return &cfg, nil\n}\n```\n\n### Custom Error Types\n\n```go\n\u002F\u002F Define domain-specific errors\ntype ValidationError struct {\n    Field   string\n    Message string\n}\n\nfunc (e *ValidationError) Error() string {\n    return fmt.Sprintf(\"validation failed on %s: %s\", e.Field, e.Message)\n}\n\n\u002F\u002F Sentinel errors for common cases\nvar (\n    ErrNotFound     = errors.New(\"resource not found\")\n    ErrUnauthorized = errors.New(\"unauthorized\")\n    ErrInvalidInput = errors.New(\"invalid input\")\n)\n```\n\n### Error Checking with errors.Is and errors.As\n\n```go\nfunc HandleError(err error) {\n    \u002F\u002F Check for specific error\n    if errors.Is(err, sql.ErrNoRows) {\n        log.Println(\"No records found\")\n        return\n    }\n\n    \u002F\u002F Check for error type\n    var validationErr *ValidationError\n    if errors.As(err, &validationErr) {\n        log.Printf(\"Validation error on field %s: %s\",\n            validationErr.Field, validationErr.Message)\n        return\n    }\n\n    \u002F\u002F Unknown error\n    log.Printf(\"Unexpected error: %v\", err)\n}\n```\n\n### Never Ignore Errors\n\n```go\n\u002F\u002F Bad: Ignoring error with blank identifier\nresult, _ := doSomething()\n\n\u002F\u002F Good: Handle or explicitly document why it's safe to ignore\nresult, err := doSomething()\nif err != nil {\n    return err\n}\n\n\u002F\u002F Acceptable: When error truly doesn't matter (rare)\n_ = writer.Close() \u002F\u002F Best-effort cleanup, error logged elsewhere\n```\n\n## Concurrency Patterns\n\n### Worker Pool\n\n```go\nfunc WorkerPool(jobs \u003C-chan Job, results chan\u003C- Result, numWorkers int) {\n    var wg sync.WaitGroup\n\n    for i := 0; i \u003C numWorkers; i++ {\n        wg.Add(1)\n        go func() {\n            defer wg.Done()\n            for job := range jobs {\n                results \u003C- process(job)\n            }\n        }()\n    }\n\n    wg.Wait()\n    close(results)\n}\n```\n\n### Context for Cancellation and Timeouts\n\n```go\nfunc FetchWithTimeout(ctx context.Context, url string) ([]byte, error) {\n    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)\n    defer cancel()\n\n    req, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\n    if err != nil {\n        return nil, fmt.Errorf(\"create request: %w\", err)\n    }\n\n    resp, err := http.DefaultClient.Do(req)\n    if err != nil {\n        return nil, fmt.Errorf(\"fetch %s: %w\", url, err)\n    }\n    defer resp.Body.Close()\n\n    return io.ReadAll(resp.Body)\n}\n```\n\n### Graceful Shutdown\n\n```go\nfunc GracefulShutdown(server *http.Server) {\n    quit := make(chan os.Signal, 1)\n    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)\n\n    \u003C-quit\n    log.Println(\"Shutting down server...\")\n\n    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n    defer cancel()\n\n    if err := server.Shutdown(ctx); err != nil {\n        log.Fatalf(\"Server forced to shutdown: %v\", err)\n    }\n\n    log.Println(\"Server exited\")\n}\n```\n\n### errgroup for Coordinated Goroutines\n\n```go\nimport \"golang.org\u002Fx\u002Fsync\u002Ferrgroup\"\n\nfunc FetchAll(ctx context.Context, urls []string) ([][]byte, error) {\n    g, ctx := errgroup.WithContext(ctx)\n    results := make([][]byte, len(urls))\n\n    for i, url := range urls {\n        i, url := i, url \u002F\u002F Capture loop variables\n        g.Go(func() error {\n            data, err := FetchWithTimeout(ctx, url)\n            if err != nil {\n                return err\n            }\n            results[i] = data\n            return nil\n        })\n    }\n\n    if err := g.Wait(); err != nil {\n        return nil, err\n    }\n    return results, nil\n}\n```\n\n### Avoiding Goroutine Leaks\n\n```go\n\u002F\u002F Bad: Goroutine leak if context is cancelled\nfunc leakyFetch(ctx context.Context, url string) \u003C-chan []byte {\n    ch := make(chan []byte)\n    go func() {\n        data, _ := fetch(url)\n        ch \u003C- data \u002F\u002F Blocks forever if no receiver\n    }()\n    return ch\n}\n\n\u002F\u002F Good: Properly handles cancellation\nfunc safeFetch(ctx context.Context, url string) \u003C-chan []byte {\n    ch := make(chan []byte, 1) \u002F\u002F Buffered channel\n    go func() {\n        data, err := fetch(url)\n        if err != nil {\n            return\n        }\n        select {\n        case ch \u003C- data:\n        case \u003C-ctx.Done():\n        }\n    }()\n    return ch\n}\n```\n\n## Interface Design\n\n### Small, Focused Interfaces\n\n```go\n\u002F\u002F Good: Single-method interfaces\ntype Reader interface {\n    Read(p []byte) (n int, err error)\n}\n\ntype Writer interface {\n    Write(p []byte) (n int, err error)\n}\n\ntype Closer interface {\n    Close() error\n}\n\n\u002F\u002F Compose interfaces as needed\ntype ReadWriteCloser interface {\n    Reader\n    Writer\n    Closer\n}\n```\n\n### Define Interfaces Where They're Used\n\n```go\n\u002F\u002F In the consumer package, not the provider\npackage service\n\n\u002F\u002F UserStore defines what this service needs\ntype UserStore interface {\n    GetUser(id string) (*User, error)\n    SaveUser(user *User) error\n}\n\ntype Service struct {\n    store UserStore\n}\n\n\u002F\u002F Concrete implementation can be in another package\n\u002F\u002F It doesn't need to know about this interface\n```\n\n### Optional Behavior with Type Assertions\n\n```go\ntype Flusher interface {\n    Flush() error\n}\n\nfunc WriteAndFlush(w io.Writer, data []byte) error {\n    if _, err := w.Write(data); err != nil {\n        return err\n    }\n\n    \u002F\u002F Flush if supported\n    if f, ok := w.(Flusher); ok {\n        return f.Flush()\n    }\n    return nil\n}\n```\n\n## Package Organization\n\n### Standard Project Layout\n\n```text\nmyproject\u002F\n├── cmd\u002F\n│   └── myapp\u002F\n│       └── main.go           # Entry point\n├── internal\u002F\n│   ├── handler\u002F              # HTTP handlers\n│   ├── service\u002F              # Business logic\n│   ├── repository\u002F           # Data access\n│   └── config\u002F               # Configuration\n├── pkg\u002F\n│   └── client\u002F               # Public API client\n├── api\u002F\n│   └── v1\u002F                   # API definitions (proto, OpenAPI)\n├── testdata\u002F                 # Test fixtures\n├── go.mod\n├── go.sum\n└── Makefile\n```\n\n### Package Naming\n\n```go\n\u002F\u002F Good: Short, lowercase, no underscores\npackage http\npackage json\npackage user\n\n\u002F\u002F Bad: Verbose, mixed case, or redundant\npackage httpHandler\npackage json_parser\npackage userService \u002F\u002F Redundant 'Service' suffix\n```\n\n### Avoid Package-Level State\n\n```go\n\u002F\u002F Bad: Global mutable state\nvar db *sql.DB\n\nfunc init() {\n    db, _ = sql.Open(\"postgres\", os.Getenv(\"DATABASE_URL\"))\n}\n\n\u002F\u002F Good: Dependency injection\ntype Server struct {\n    db *sql.DB\n}\n\nfunc NewServer(db *sql.DB) *Server {\n    return &Server{db: db}\n}\n```\n\n## Struct Design\n\n### Functional Options Pattern\n\n```go\ntype Server struct {\n    addr    string\n    timeout time.Duration\n    logger  *log.Logger\n}\n\ntype Option func(*Server)\n\nfunc WithTimeout(d time.Duration) Option {\n    return func(s *Server) {\n        s.timeout = d\n    }\n}\n\nfunc WithLogger(l *log.Logger) Option {\n    return func(s *Server) {\n        s.logger = l\n    }\n}\n\nfunc NewServer(addr string, opts ...Option) *Server {\n    s := &Server{\n        addr:    addr,\n        timeout: 30 * time.Second, \u002F\u002F default\n        logger:  log.Default(),    \u002F\u002F default\n    }\n    for _, opt := range opts {\n        opt(s)\n    }\n    return s\n}\n\n\u002F\u002F Usage\nserver := NewServer(\":8080\",\n    WithTimeout(60*time.Second),\n    WithLogger(customLogger),\n)\n```\n\n### Embedding for Composition\n\n```go\ntype Logger struct {\n    prefix string\n}\n\nfunc (l *Logger) Log(msg string) {\n    fmt.Printf(\"[%s] %s\\n\", l.prefix, msg)\n}\n\ntype Server struct {\n    *Logger \u002F\u002F Embedding - Server gets Log method\n    addr    string\n}\n\nfunc NewServer(addr string) *Server {\n    return &Server{\n        Logger: &Logger{prefix: \"SERVER\"},\n        addr:   addr,\n    }\n}\n\n\u002F\u002F Usage\ns := NewServer(\":8080\")\ns.Log(\"Starting...\") \u002F\u002F Calls embedded Logger.Log\n```\n\n## Memory and Performance\n\n### Preallocate Slices When Size is Known\n\n```go\n\u002F\u002F Bad: Grows slice multiple times\nfunc processItems(items []Item) []Result {\n    var results []Result\n    for _, item := range items {\n        results = append(results, process(item))\n    }\n    return results\n}\n\n\u002F\u002F Good: Single allocation\nfunc processItems(items []Item) []Result {\n    results := make([]Result, 0, len(items))\n    for _, item := range items {\n        results = append(results, process(item))\n    }\n    return results\n}\n```\n\n### Use sync.Pool for Frequent Allocations\n\n```go\nvar bufferPool = sync.Pool{\n    New: func() interface{} {\n        return new(bytes.Buffer)\n    },\n}\n\nfunc ProcessRequest(data []byte) []byte {\n    buf := bufferPool.Get().(*bytes.Buffer)\n    defer func() {\n        buf.Reset()\n        bufferPool.Put(buf)\n    }()\n\n    buf.Write(data)\n    \u002F\u002F Process...\n    return buf.Bytes()\n}\n```\n\n### Avoid String Concatenation in Loops\n\n```go\n\u002F\u002F Bad: Creates many string allocations\nfunc join(parts []string) string {\n    var result string\n    for _, p := range parts {\n        result += p + \",\"\n    }\n    return result\n}\n\n\u002F\u002F Good: Single allocation with strings.Builder\nfunc join(parts []string) string {\n    var sb strings.Builder\n    for i, p := range parts {\n        if i > 0 {\n            sb.WriteString(\",\")\n        }\n        sb.WriteString(p)\n    }\n    return sb.String()\n}\n\n\u002F\u002F Best: Use standard library\nfunc join(parts []string) string {\n    return strings.Join(parts, \",\")\n}\n```\n\n## Go Tooling Integration\n\n### Essential Commands\n\n```bash\n# Build and run\ngo build .\u002F...\ngo run .\u002Fcmd\u002Fmyapp\n\n# Testing\ngo test .\u002F...\ngo test -race .\u002F...\ngo test -cover .\u002F...\n\n# Static analysis\ngo vet .\u002F...\nstaticcheck .\u002F...\ngolangci-lint run\n\n# Module management\ngo mod tidy\ngo mod verify\n\n# Formatting\ngofmt -w .\ngoimports -w .\n```\n\n### Recommended Linter Configuration (.golangci.yml)\n\n```yaml\nlinters:\n  enable:\n    - errcheck\n    - gosimple\n    - govet\n    - ineffassign\n    - staticcheck\n    - unused\n    - gofmt\n    - goimports\n    - misspell\n    - unconvert\n    - unparam\n\nlinters-settings:\n  errcheck:\n    check-type-assertions: true\n  govet:\n    enable:\n      - shadow\n\nissues:\n  exclude-use-default: false\n```\n\n## Quick Reference: Go Idioms\n\n| Idiom | Description |\n|-------|-------------|\n| Accept interfaces, return structs | Functions accept interface params, return concrete types |\n| Errors are values | Treat errors as first-class values, not exceptions |\n| Don't communicate by sharing memory | Use channels for coordination between goroutines |\n| Make the zero value useful | Types should work without explicit initialization |\n| A little copying is better than a little dependency | Avoid unnecessary external dependencies |\n| Clear is better than clever | Prioritize readability over cleverness |\n| gofmt is no one's favorite but everyone's friend | Always format with gofmt\u002Fgoimports |\n| Return early | Handle errors first, keep happy path unindented |\n\n## Anti-Patterns to Avoid\n\n```go\n\u002F\u002F Bad: Naked returns in long functions\nfunc process() (result int, err error) {\n    \u002F\u002F ... 50 lines ...\n    return \u002F\u002F What is being returned?\n}\n\n\u002F\u002F Bad: Using panic for control flow\nfunc GetUser(id string) *User {\n    user, err := db.Find(id)\n    if err != nil {\n        panic(err) \u002F\u002F Don't do this\n    }\n    return user\n}\n\n\u002F\u002F Bad: Passing context in struct\ntype Request struct {\n    ctx context.Context \u002F\u002F Context should be first param\n    ID  string\n}\n\n\u002F\u002F Good: Context as first parameter\nfunc ProcessRequest(ctx context.Context, id string) error {\n    \u002F\u002F ...\n}\n\n\u002F\u002F Bad: Mixing value and pointer receivers\ntype Counter struct{ n int }\nfunc (c Counter) Value() int { return c.n }    \u002F\u002F Value receiver\nfunc (c *Counter) Increment() { c.n++ }        \u002F\u002F Pointer receiver\n\u002F\u002F Pick one style and be consistent\n```\n\n**Remember**: Go code should be boring in the best way - predictable, consistent, and easy to understand. When in doubt, keep it simple.\n","# Go Development Patterns\n\nIdiomatic Go patterns and best practices for building robust, efficient, and maintainable applications.\n\n## When to Activate\n\n- Writing new Go code\n- Reviewing Go code\n- Refactoring existing Go code\n- Designing Go packages\u002Fmodules\n\n## Core Principles\n\n### 1. Simplicity and Clarity\n\nGo favors simplicity over cleverness. Code should be obvious and easy to read.\n\n```go\n\u002F\u002F Good: Clear and direct\nfunc GetUser(id string) (*User, error) {\n    user, err := db.FindUser(id)\n    if err != nil {\n        return nil, fmt.Errorf(\"get user %s: %w\", id, err)\n    }\n    return user, nil\n}\n\n\u002F\u002F Bad: Overly clever\nfunc GetUser(id string) (*User, error) {\n    return func() (*User, error) {\n        if u, e := db.FindUser(id); e == nil {\n            return u, nil\n        } else {\n            return nil, e\n        }\n    }()\n}\n```\n\n### 2. Make the Zero Value Useful\n\nDesign types so their zero value is immediately usable without initialization.\n\n```go\n\u002F\u002F Good: Zero value is useful\ntype Counter struct {\n    mu    sync.Mutex\n    count int \u002F\u002F zero value is 0, ready to use\n}\n\nfunc (c *Counter) Inc() {\n    c.mu.Lock()\n    c.count++\n    c.mu.Unlock()\n}\n\n\u002F\u002F Good: bytes.Buffer works with zero value\nvar buf bytes.Buffer\nbuf.WriteString(\"hello\")\n\n\u002F\u002F Bad: Requires initialization\ntype BadCounter struct {\n    counts map[string]int \u002F\u002F nil map will panic\n}\n```\n\n### 3. Accept Interfaces, Return Structs\n\nFunctions should accept interface parameters and return concrete types.\n\n```go\n\u002F\u002F Good: Accepts interface, returns concrete type\nfunc ProcessData(r io.Reader) (*Result, error) {\n    data, err := io.ReadAll(r)\n    if err != nil {\n        return nil, err\n    }\n    return &Result{Data: data}, nil\n}\n\n\u002F\u002F Bad: Returns interface (hides implementation details unnecessarily)\nfunc ProcessData(r io.Reader) (io.Reader, error) {\n    \u002F\u002F ...\n}\n```\n\n## Error Handling Patterns\n\n### Error Wrapping with Context\n\n```go\n\u002F\u002F Good: Wrap errors with context\nfunc LoadConfig(path string) (*Config, error) {\n    data, err := os.ReadFile(path)\n    if err != nil {\n        return nil, fmt.Errorf(\"load config %s: %w\", path, err)\n    }\n\n    var cfg Config\n    if err := json.Unmarshal(data, &cfg); err != nil {\n        return nil, fmt.Errorf(\"parse config %s: %w\", path, err)\n    }\n\n    return &cfg, nil\n}\n```\n\n### Custom Error Types\n\n```go\n\u002F\u002F Define domain-specific errors\ntype ValidationError struct {\n    Field   string\n    Message string\n}\n\nfunc (e *ValidationError) Error() string {\n    return fmt.Sprintf(\"validation failed on %s: %s\", e.Field, e.Message)\n}\n\n\u002F\u002F Sentinel errors for common cases\nvar (\n    ErrNotFound     = errors.New(\"resource not found\")\n    ErrUnauthorized = errors.New(\"unauthorized\")\n    ErrInvalidInput = errors.New(\"invalid input\")\n)\n```\n\n### Error Checking with errors.Is and errors.As\n\n```go\nfunc HandleError(err error) {\n    \u002F\u002F Check for specific error\n    if errors.Is(err, sql.ErrNoRows) {\n        log.Println(\"No records found\")\n        return\n    }\n\n    \u002F\u002F Check for error type\n    var validationErr *ValidationError\n    if errors.As(err, &validationErr) {\n        log.Printf(\"Validation error on field %s: %s\",\n            validationErr.Field, validationErr.Message)\n        return\n    }\n\n    \u002F\u002F Unknown error\n    log.Printf(\"Unexpected error: %v\", err)\n}\n```\n\n### Never Ignore Errors\n\n```go\n\u002F\u002F Bad: Ignoring error with blank identifier\nresult, _ := doSomething()\n\n\u002F\u002F Good: Handle or explicitly document why it's safe to ignore\nresult, err := doSomething()\nif err != nil {\n    return err\n}\n\n\u002F\u002F Acceptable: When error truly doesn't matter (rare)\n_ = writer.Close() \u002F\u002F Best-effort cleanup, error logged elsewhere\n```\n\n## Concurrency Patterns\n\n### Worker Pool\n\n```go\nfunc WorkerPool(jobs \u003C-chan Job, results chan\u003C- Result, numWorkers int) {\n    var wg sync.WaitGroup\n\n    for i := 0; i \u003C numWorkers; i++ {\n        wg.Add(1)\n        go func() {\n            defer wg.Done()\n            for job := range jobs {\n                results \u003C- process(job)\n            }\n        }()\n    }\n\n    wg.Wait()\n    close(results)\n}\n```\n\n### Context for Cancellation and Timeouts\n\n```go\nfunc FetchWithTimeout(ctx context.Context, url string) ([]byte, error) {\n    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)\n    defer cancel()\n\n    req, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\n    if err != nil {\n        return nil, fmt.Errorf(\"create request: %w\", err)\n    }\n\n    resp, err := http.DefaultClient.Do(req)\n    if err != nil {\n        return nil, fmt.Errorf(\"fetch %s: %w\", url, err)\n    }\n    defer resp.Body.Close()\n\n    return io.ReadAll(resp.Body)\n}\n```\n\n### Graceful Shutdown\n\n```go\nfunc GracefulShutdown(server *http.Server) {\n    quit := make(chan os.Signal, 1)\n    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)\n\n    \u003C-quit\n    log.Println(\"Shutting down server...\")\n\n    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n    defer cancel()\n\n    if err := server.Shutdown(ctx); err != nil {\n        log.Fatalf(\"Server forced to shutdown: %v\", err)\n    }\n\n    log.Println(\"Server exited\")\n}\n```\n\n### errgroup for Coordinated Goroutines\n\n```go\nimport \"golang.org\u002Fx\u002Fsync\u002Ferrgroup\"\n\nfunc FetchAll(ctx context.Context, urls []string) ([][]byte, error) {\n    g, ctx := errgroup.WithContext(ctx)\n    results := make([][]byte, len(urls))\n\n    for i, url := range urls {\n        i, url := i, url \u002F\u002F Capture loop variables\n        g.Go(func() error {\n            data, err := FetchWithTimeout(ctx, url)\n            if err != nil {\n                return err\n            }\n            results[i] = data\n            return nil\n        })\n    }\n\n    if err := g.Wait(); err != nil {\n        return nil, err\n    }\n    return results, nil\n}\n```\n\n### Avoiding Goroutine Leaks\n\n```go\n\u002F\u002F Bad: Goroutine leak if context is cancelled\nfunc leakyFetch(ctx context.Context, url string) \u003C-chan []byte {\n    ch := make(chan []byte)\n    go func() {\n        data, _ := fetch(url)\n        ch \u003C- data \u002F\u002F Blocks forever if no receiver\n    }()\n    return ch\n}\n\n\u002F\u002F Good: Properly handles cancellation\nfunc safeFetch(ctx context.Context, url string) \u003C-chan []byte {\n    ch := make(chan []byte, 1) \u002F\u002F Buffered channel\n    go func() {\n        data, err := fetch(url)\n        if err != nil {\n            return\n        }\n        select {\n        case ch \u003C- data:\n        case \u003C-ctx.Done():\n        }\n    }()\n    return ch\n}\n```\n\n## Interface Design\n\n### Small, Focused Interfaces\n\n```go\n\u002F\u002F Good: Single-method interfaces\ntype Reader interface {\n    Read(p []byte) (n int, err error)\n}\n\ntype Writer interface {\n    Write(p []byte) (n int, err error)\n}\n\ntype Closer interface {\n    Close() error\n}\n\n\u002F\u002F Compose interfaces as needed\ntype ReadWriteCloser interface {\n    Reader\n    Writer\n    Closer\n}\n```\n\n### Define Interfaces Where They're Used\n\n```go\n\u002F\u002F In the consumer package, not the provider\npackage service\n\n\u002F\u002F UserStore defines what this service needs\ntype UserStore interface {\n    GetUser(id string) (*User, error)\n    SaveUser(user *User) error\n}\n\ntype Service struct {\n    store UserStore\n}\n\n\u002F\u002F Concrete implementation can be in another package\n\u002F\u002F It doesn't need to know about this interface\n```\n\n### Optional Behavior with Type Assertions\n\n```go\ntype Flusher interface {\n    Flush() error\n}\n\nfunc WriteAndFlush(w io.Writer, data []byte) error {\n    if _, err := w.Write(data); err != nil {\n        return err\n    }\n\n    \u002F\u002F Flush if supported\n    if f, ok := w.(Flusher); ok {\n        return f.Flush()\n    }\n    return nil\n}\n```\n\n## Package Organization\n\n### Standard Project Layout\n\n```text\nmyproject\u002F\n├── cmd\u002F\n│   └── myapp\u002F\n│       └── main.go           # Entry point\n├── internal\u002F\n│   ├── handler\u002F              # HTTP handlers\n│   ├── service\u002F              # Business logic\n│   ├── repository\u002F           # Data access\n│   └── config\u002F               # Configuration\n├── pkg\u002F\n│   └── client\u002F               # Public API client\n├── api\u002F\n│   └── v1\u002F                   # API definitions (proto, OpenAPI)\n├── testdata\u002F                 # Test fixtures\n├── go.mod\n├── go.sum\n└── Makefile\n```\n\n### Package Naming\n\n```go\n\u002F\u002F Good: Short, lowercase, no underscores\npackage http\npackage json\npackage user\n\n\u002F\u002F Bad: Verbose, mixed case, or redundant\npackage httpHandler\npackage json_parser\npackage userService \u002F\u002F Redundant 'Service' suffix\n```\n\n### Avoid Package-Level State\n\n```go\n\u002F\u002F Bad: Global mutable state\nvar db *sql.DB\n\nfunc init() {\n    db, _ = sql.Open(\"postgres\", os.Getenv(\"DATABASE_URL\"))\n}\n\n\u002F\u002F Good: Dependency injection\ntype Server struct {\n    db *sql.DB\n}\n\nfunc NewServer(db *sql.DB) *Server {\n    return &Server{db: db}\n}\n```\n\n## Struct Design\n\n### Functional Options Pattern\n\n```go\ntype Server struct {\n    addr    string\n    timeout time.Duration\n    logger  *log.Logger\n}\n\ntype Option func(*Server)\n\nfunc WithTimeout(d time.Duration) Option {\n    return func(s *Server) {\n        s.timeout = d\n    }\n}\n\nfunc WithLogger(l *log.Logger) Option {\n    return func(s *Server) {\n        s.logger = l\n    }\n}\n\nfunc NewServer(addr string, opts ...Option) *Server {\n    s := &Server{\n        addr:    addr,\n        timeout: 30 * time.Second, \u002F\u002F default\n        logger:  log.Default(),    \u002F\u002F default\n    }\n    for _, opt := range opts {\n        opt(s)\n    }\n    return s\n}\n\n\u002F\u002F Usage\nserver := NewServer(\":8080\",\n    WithTimeout(60*time.Second),\n    WithLogger(customLogger),\n)\n```\n\n### Embedding for Composition\n\n```go\ntype Logger struct {\n    prefix string\n}\n\nfunc (l *Logger) Log(msg string) {\n    fmt.Printf(\"[%s] %s\\n\", l.prefix, msg)\n}\n\ntype Server struct {\n    *Logger \u002F\u002F Embedding - Server gets Log method\n    addr    string\n}\n\nfunc NewServer(addr string) *Server {\n    return &Server{\n        Logger: &Logger{prefix: \"SERVER\"},\n        addr:   addr,\n    }\n}\n\n\u002F\u002F Usage\ns := NewServer(\":8080\")\ns.Log(\"Starting...\") \u002F\u002F Calls embedded Logger.Log\n```\n\n## Memory and Performance\n\n### Preallocate Slices When Size is Known\n\n```go\n\u002F\u002F Bad: Grows slice multiple times\nfunc processItems(items []Item) []Result {\n    var results []Result\n    for _, item := range items {\n        results = append(results, process(item))\n    }\n    return results\n}\n\n\u002F\u002F Good: Single allocation\nfunc processItems(items []Item) []Result {\n    results := make([]Result, 0, len(items))\n    for _, item := range items {\n        results = append(results, process(item))\n    }\n    return results\n}\n```\n\n### Use sync.Pool for Frequent Allocations\n\n```go\nvar bufferPool = sync.Pool{\n    New: func() interface{} {\n        return new(bytes.Buffer)\n    },\n}\n\nfunc ProcessRequest(data []byte) []byte {\n    buf := bufferPool.Get().(*bytes.Buffer)\n    defer func() {\n        buf.Reset()\n        bufferPool.Put(buf)\n    }()\n\n    buf.Write(data)\n    \u002F\u002F Process...\n    return buf.Bytes()\n}\n```\n\n### Avoid String Concatenation in Loops\n\n```go\n\u002F\u002F Bad: Creates many string allocations\nfunc join(parts []string) string {\n    var result string\n    for _, p := range parts {\n        result += p + \",\"\n    }\n    return result\n}\n\n\u002F\u002F Good: Single allocation with strings.Builder\nfunc join(parts []string) string {\n    var sb strings.Builder\n    for i, p := range parts {\n        if i > 0 {\n            sb.WriteString(\",\")\n        }\n        sb.WriteString(p)\n    }\n    return sb.String()\n}\n\n\u002F\u002F Best: Use standard library\nfunc join(parts []string) string {\n    return strings.Join(parts, \",\")\n}\n```\n\n## Go Tooling Integration\n\n### Essential Commands\n\n```bash\n# Build and run\ngo build .\u002F...\ngo run .\u002Fcmd\u002Fmyapp\n\n# Testing\ngo test .\u002F...\ngo test -race .\u002F...\ngo test -cover .\u002F...\n\n# Static analysis\ngo vet .\u002F...\nstaticcheck .\u002F...\ngolangci-lint run\n\n# Module management\ngo mod tidy\ngo mod verify\n\n# Formatting\ngofmt -w .\ngoimports -w .\n```\n\n### Recommended Linter Configuration (.golangci.yml)\n\n```yaml\nlinters:\n  enable:\n    - errcheck\n    - gosimple\n    - govet\n    - ineffassign\n    - staticcheck\n    - unused\n    - gofmt\n    - goimports\n    - misspell\n    - unconvert\n    - unparam\n\nlinters-settings:\n  errcheck:\n    check-type-assertions: true\n  govet:\n    enable:\n      - shadow\n\nissues:\n  exclude-use-default: false\n```\n\n## Quick Reference: Go Idioms\n\n| Idiom | Description |\n|-------|-------------|\n| Accept interfaces, return structs | Functions accept interface params, return concrete types |\n| Errors are values | Treat errors as first-class values, not exceptions |\n| Don't communicate by sharing memory | Use channels for coordination between goroutines |\n| Make the zero value useful | Types should work without explicit initialization |\n| A little copying is better than a little dependency | Avoid unnecessary external dependencies |\n| Clear is better than clever | Prioritize readability over cleverness |\n| gofmt is no one's favorite but everyone's friend | Always format with gofmt\u002Fgoimports |\n| Return early | Handle errors first, keep happy path unindented |\n\n## Anti-Patterns to Avoid\n\n```go\n\u002F\u002F Bad: Naked returns in long functions\nfunc process() (result int, err error) {\n    \u002F\u002F ... 50 lines ...\n    return \u002F\u002F What is being returned?\n}\n\n\u002F\u002F Bad: Using panic for control flow\nfunc GetUser(id string) *User {\n    user, err := db.Find(id)\n    if err != nil {\n        panic(err) \u002F\u002F Don't do this\n    }\n    return user\n}\n\n\u002F\u002F Bad: Passing context in struct\ntype Request struct {\n    ctx context.Context \u002F\u002F Context should be first param\n    ID  string\n}\n\n\u002F\u002F Good: Context as first parameter\nfunc ProcessRequest(ctx context.Context, id string) error {\n    \u002F\u002F ...\n}\n\n\u002F\u002F Bad: Mixing value and pointer receivers\ntype Counter struct{ n int }\nfunc (c Counter) Value() int { return c.n }    \u002F\u002F Value receiver\nfunc (c *Counter) Increment() { c.n++ }        \u002F\u002F Pointer receiver\n\u002F\u002F Pick one style and be consistent\n```\n\n**Remember**: Go code should be boring in the best way - predictable, consistent, and easy to understand. When in doubt, keep it simple.\n",{"name":5,"tags":49,"tools":52,"source":55,"license":14,"description":7,"source_path":56,"source_commit":57},[50,51,34,29],"engineering","backend",[53,54],"monograph_query","monograph_context","https:\u002F\u002Fgithub.com\u002Faffaan-m\u002FECC","skills\u002Fgolang-patterns","bf70150eb2df8070024e5bdf08e4aa08959e2735","main","f7cd4595d0f8959822163e14f9787117765c931a","packages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fgolang-patterns",2,"https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind","https:\u002F\u002Fmonoes.github.io\u002Fmonomind\u002F","https:\u002F\u002Fgithub.com\u002Fmonoes","https:\u002F\u002Fmonoes.me","2026-11-10 01:53:48",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add monoes\u002Fmonomind --skill golang-patterns",{"tool":73,"command":74},"bunx","bunx skills add monoes\u002Fmonomind --skill golang-patterns",{"tool":76,"command":77},"pnpm","pnpm dlx skills add monoes\u002Fmonomind --skill golang-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fgolang-patterns\u002FSKILL.md",true,[81],{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":15},"LICENSE.txt","LICENSE","许可证",1071,[87,114,143,170,194,221],{"skillNo":88,"name":89,"nameZh":6,"description":90,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":113},"01M71PB3SHWKMNJM6MD65VX8D6","zk-steward","Org role guidance for a ZK steward: engineer zero-knowledge proof systems with circuit design, SNARK vs STARK choice and security review. This is zero-knowledge cryptography, not Zettelkasten note-taking.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fzk-steward\u002FSKILL.md",[],[95,96,97,98,99,100,42,101,102,39,103,104,105,106,107,108,109,110,111,112],"zk","zk steward","steward","zero-knowledge","engineer","choice","knowledge","impact","snark","review","monomind","security review","stark","zettelkasten","cryptography","security","org","blockchain","2026-11-10 13:02:02",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":118,"sourceHtmlUrl":119,"categories":120,"keywords":129,"publishedAt":113},"01M71PB18SDG28WBKPKJNB814K","writing-plans","Use when you have a spec or requirements for a multi-step coding task and must write an implementation plan before touching code. Produces bite-sized TDD tasks with exact file paths, code and commands for an engineer with zero context.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwriting-plans\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwriting-plans\u002FSKILL.md",[121,124],{"categoryNo":122,"categoryName":123,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":125,"categoryName":126,"taxonomyType":127,"taxonomyTypeDesc":128},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[41,130,131,99,132,133,40,134,39,38,135,136,137,138,139,140,141,33,32,142],"writing plans","plans","superpowers","implementation plan","you","tasks","plan","product","write","commands","paths","suggest","ZeRO",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":147,"sourceHtmlUrl":148,"categories":149,"keywords":153,"publishedAt":113},"01M71PAXFM488X9ARXK0T04TF5","write-spec","Write a feature spec or PRD from a problem statement or feature idea. Use when turning a vague idea or user request into a structured document, scoping a feature with goals and non-goals, defining success metrics and acceptance criteria, or breaking a big ask into a phased spec.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-spec\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-spec\u002FSKILL.md",[150],{"categoryNo":151,"categoryName":152,"taxonomyType":127,"taxonomyTypeDesc":128},"01JBSEEDCAT000000000000031","产品经理",[138,154,155,156,157,101,158,40,159,160,161,137,162,163,164,165,166,167,168,169],"write spec","spec","user request","problem","acceptance","ask","vague","work","request","scoping","idea","metrics","feature","problem statement","use","document",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":174,"sourceHtmlUrl":175,"categories":176,"keywords":180,"publishedAt":113},"01M71PASSZY800C0RPEARBS918","write-query","Write optimized SQL for your dialect with best practices. Use when translating a natural-language data need into SQL, building a multi-CTE query with joins and aggregations, optimizing a query against a large partitioned table, or getting dialect-specific syntax for Snowflake, BigQuery, Postgres, etc.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-query\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-query\u002FSKILL.md",[177],{"categoryNo":178,"categoryName":179,"taxonomyType":127,"taxonomyTypeDesc":128},"01JBSEEDCAT000000000000033","数据分析师",[39,138,181,182,28,183,101,168,40,184,185,186,187,161,188,189,190,191,192,193],"write query","postgres","snowflake","best practices","natural-language","with","multi","github","sql","https","syntax","plugins","data",{"skillNo":195,"name":196,"nameZh":6,"description":197,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":198,"categories":199,"keywords":206,"publishedAt":113},"01M71PAPTX0T3PF6ETFVR96SJJ","workflow-automation","Org role guidance for workflow automation: build and maintain CI\u002FCD definitions in GitHub Actions or equivalent: triggers, jobs, matrices, caching. Covers path filters, dependency caching, parallel jobs, timeouts and fail-fast ordering.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fworkflow-automation\u002FSKILL.md",[200,203],{"categoryNo":201,"categoryName":202,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":204,"categoryName":205,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[207,208,209,210,28,211,212,213,214,102,215,216,217,39,105,188,218,219,220,190],"Workflow Automation","automation","workflow","parallel","actions","ci","triggers","github actions","maintain","filters","caching","build","dependency","devops",{"skillNo":222,"name":223,"nameZh":6,"description":224,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":225,"categories":226,"keywords":228,"publishedAt":113},"01M71PAM19Z1XTV9NPCFSE2MY8","workflow-architect","Org role guidance for a workflow architect: map full workflow trees for systems, user journeys and agents, covering every branch and failure. Covers discovering workflows from code, handoff contracts, timeouts, recovery paths and observable state.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fworkflow-architect\u002FSKILL.md",[227],{"categoryNo":204,"categoryName":205,"taxonomyType":21,"taxonomyTypeDesc":22},[209,229,230,231,232,233,234,28,235,236,38,237,238,239,105,188,240,241,190,242],"workflow architect","architect","trees","user journeys","branch","planning","map","workflows","architecture","state","leadership","recovery","operations","systems"]