算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
best-practices【设计与创意】Enforces Go idioms and best practices including error handling, interface design, testing conventions, and code organization for maintainable applications.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: best-practices description: Enforces Go idioms and best practices including error handling, interface design, testing conventions, and code organization for maintainable applications. license: MIT compatibility: opencode metadata: version: "1.0.0" domain: go role: implementation scope: implementation output-format: code content-types:
Senior engineer enforcing idiomatic Go conventions — writing clean, maintainable Go code that reads like well-structured English. This skill covers error handling, interface design, naming, package organization, and the conventions that make Go code predictable and reviewable.
cache, not cachetypes)context.Context for all operations that span request boundaries// Package doc and // Function doc commentsUse this skill when:
Avoid this skill for:
unsafe patterns instead)Evaluate the Code Structure — Check package organization, naming, and exported symbol visibility. Checkpoint: Every exported function and type has a godoc comment explaining its purpose.
Enforce Error Handling — Verify all errors are explicitly handled at call sites. No silent swallowing.
Checkpoint: Every err != nil check has a meaningful action (return, log with context, retry).
Review Interface Design — Ensure interfaces are small, consumer-specific, and defined by consumers. Checkpoint: Interfaces should fit on one screen. If an interface has more than 3-4 methods, consider splitting.
Check Naming Conventions — Verify names follow Go's naming rules: short, precise, camelCase for exports. Checkpoint: Package names are lowercase, single words, no underscores.
Validate Testing Coverage — Ensure table-driven tests cover happy path, error paths, and edge cases. Checkpoint: Every exported function has at least one test case for normal input and one for error input.
Go's error handling must be explicit. Ignoring errors is a bug, not an optimization.
// ❌ BAD: ignoring an error silently — the caller has no way to know something failed
func ProcessFile(path string) error {
data, err := os.ReadFile(path)
// err is ignored — file might not exist, permissions denied, etc.
_ = err
content := strings.ToUpper(string(data))
return nil
}
What's wrong:
_ = err, hiding failure from the callerreturn nil) even when the file read failed// ProcessFile reads a file, uppercases its content, and returns the result.
// Returns os.PathError if the file cannot be read.
func ProcessFile(path string) ([]byte, error) {
if path == "" {
return nil, fmt.Errorf("process file: path must not be empty")
}
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("process file: read %s: %w", path, err)
}
return bytes.ToUpper(data), nil
}
Why this works:
%w for error chain inspection([]byte, error) makes success/failure explicit to the callerGo interfaces should be small, consumer-defined, and focused.
// ❌ BAD: interface defined by the implementer, not the consumer
// Forces consumers to depend on methods they don't use
type Service interface {
// A service that does everything
CreateUser(ctx context.Context, req CreateUserRequest) (*User, error)
UpdateUser(ctx context.Context, id string, req UpdateUserRequest) error
DeleteUser(ctx context.Context, id string) error
GetUser(ctx context.Context, id string) (*User, error)
ListUsers(ctx context.Context, filter ListFilter) ([]*User, error)
SendEmail(ctx context.Context, to string, subject string, body string) error
GenerateReport(ctx context.Context, format string) ([]byte, error)
}
What's wrong:
GetUser still depend on SendEmail and GenerateReport// UserRepository defines operations for user persistence.
// Implemented by concrete types; consumed by handlers and services.
type UserRepository interface {
GetByID(ctx context.Context, id string) (*User, error)
Create(ctx context.Context, user *User) error
Update(ctx context.Context, user *User) error
Delete(ctx context.Context, id string) error
}
// EmailService defines operations for sending email.
type EmailService interface {
Send(ctx context.Context, msg EmailMessage) error
}
// ListableUsers is a constraint for types that support user listing.
type ListableUsers interface {
ListUsers(ctx context.Context, filter ListFilter) ([]*User, error)
}
Why this works:
Context propagation is essential for cancellable, deadline-aware operations.
// ❌ BAD: database query ignores context — cannot be cancelled or timed out
func GetUserByID(id string) (*User, error) {
row := db.QueryRow("SELECT id, name, email FROM users WHERE id = $1", id)
// no context — query runs forever if the DB is slow
var user User
err := row.Scan(&user.ID, &user.Name, &user.Email)
if err != nil {
return nil, fmt.Errorf("get user: %w", err)
}
return &user, nil
}
What's wrong:
// GetUserByID retrieves a user by their unique ID.
// The operation is cancellable via ctx and respects its deadline.
func GetUserByID(ctx context.Context, id string) (*User, error) {
if id == "" {
return nil, fmt.Errorf("get user by id: id must not be empty")
}
row := db.QueryRowContext(ctx,
"SELECT id, name, email FROM users WHERE id = $1", id,
)
var user User
if err := row.Scan(&user.ID, &user.Name, &user.Email); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, fmt.Errorf("get user by id: user %s not found", id)
}
return nil, fmt.Errorf("get user by id: %w", err)
}
return &user, nil
}
Why this works:
QueryRowContext respects the deadline — no hung queries%wcontext.Context for all operations that span request or request-like boundarieserrors.Is and errors.As for error inspection instead of string comparison_ = err or blank identifierpanic() for error handling — only for truly unrecoverable conditions at startupinterface{} — use any (Go 1.18+) for untyped values| Skill | Purpose |
|---|---|
modular-design | Designs package boundaries and dependency injection architecture |
cloud-development | Cloud-native patterns (graceful shutdown, health checks, config) |
testing-strategies | Table-driven tests, mocks, benchmarks, and integration testing |
error-handling | Custom error types, retry patterns, and failure recovery strategies |
Authoritative documentation links for this skill's domain. The model follows markdown links at load time to resolve external references and inline content.