Golang Patterns

affaan-m/ECC/.kiro/skills/golang-patterns

作者 affaan-mef648e01899ba3e8dc6371642deaaf64b4477775无许可证275K 个星标收录于 2026年10月9日更新于 2026年10月9日仓库4天前更新

Go-specific design patterns and best practices including functional options, small interfaces, dependency injection, concurrency patterns, error handling, and package organization. Use when working with Go code to apply idiomatic Go patterns.

AI 生成的概览

关于地道 Go 设计模式、并发、错误处理与项目结构的参考指南。

功能
该技能提供 Go 特有的设计模式与最佳实践,涵盖函数式选项、小接口、依赖注入、并发模式、错误处理、包组织以及测试模式。每个主题都配有简短代码示例和所述优点,例如构造函数、工作池、上下文传递、错误包装、哨兵错误和表驱动测试。它产出的是参考指南与示例代码,而不是运行任何工具。
适用场景
适用于设计 Go API 与包、实现并发系统、组织 Go 项目结构、编写地道 Go 代码或重构 Go 代码库时。它面向 Go 源文件和模块文件的相关工作。
运行要求
不附带脚本或工具,仅为说明性内容。应用其中的示例需要 Go 工具链,并熟悉所示标准库包,如 context、sync、errors、fmt 和 testing。

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:

go
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

go
// Good: Small, focused interface defined at point of usetype 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:

go
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

go
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:

go
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

go
if err != nil {    return fmt.Errorf("failed to fetch user %s: %w", id, err)}

Custom Errors

go
type ValidationError struct {    Field string    Msg   string}
func (e *ValidationError) Error() string {    return fmt.Sprintf("%s: %s", e.Field, e.Msg)}

Sentinel Errors

go
var (    ErrNotFound = errors.New("not found")    ErrInvalid  = errors.New("invalid input"))
// Check with errors.Isif 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: user.User not user.UserModel
  • Use internal/ for private code
  • Keep main package minimal

Testing Patterns

Table-Driven Tests

go
func TestValidate(t *testing.T) {    tests := []struct {        name    string        input   string        wantErr bool    }{        {"valid", "[email protected]", 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

go
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

来源与署名

来源:affaan-m/ECC位于.kiro/skills/golang-patterns提交ef648e0

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架