提供地道 Go 语言模式与最佳实践,帮助构建健壮高效且易维护的应用
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "golang-patterns" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/skills/golang-patterns/SKILL.md 2. 保存为 ~/.claude/skills/golang-patterns/SKILL.md 3. 装好后重载技能,告诉我可以用了
请用符合 Go 惯用法的方式,设计一个并发任务处理器示例:包含 worker pool、context 取消、错误传递与优雅关闭,并解释为什么这样设计。
一份符合 Go 最佳实践的并发示例代码,并附上关键设计说明。
这是我当前的 Go 项目目录与部分代码,请按照 Go 社区常见约定,建议更清晰的包结构、命名方式、接口边界与错误处理策略。
针对项目结构、命名和模块边界的重构建议,附示例目录与代码调整方向。
请审查这段 Go 代码,指出不符合 idiomatic Go 的地方,包括命名、错误处理、切片与 map 使用、接口设计和性能问题,并给出改进版本。
一份带问题清单的代码审查结果,以及更符合 Go 规范的改进代码。
Idiomatic Go patterns and best practices for building robust, efficient, and maintainable applications.
Go favors simplicity over cleverness. Code should be obvious and easy to read.
// Good: Clear and direct
func GetUser(id string) (*User, error) {
user, err := db.FindUser(id)
if err != nil {
return nil, fmt.Errorf("get user %s: %w", id, err)
}
return user, nil
}
// Bad: Overly clever
func GetUser(id string) (*User, error) {
return func() (*User, error) {
if u, e := db.FindUser(id); e == nil {
return u, nil
} else {
return nil, e
}
}()
}
Design types so their zero value is immediately usable without initialization.
// Good: Zero value is useful
type Counter struct {
mu sync.Mutex
count int // zero value is 0, ready to use
}
func (c *Counter) Inc() {
c.mu.Lock()
c.count++
c.mu.Unlock()
}
// Good: bytes.Buffer works with zero value
var buf bytes.Buffer
buf.WriteString("hello")
// Bad: Requires initialization
type BadCounter struct {
counts map[string]int // nil map will panic
}
Functions should accept interface parameters and return concrete types.
// Good: Accepts interface, returns concrete type
func ProcessData(r io.Reader) (*Result, error) {
data, err := io.ReadAll(r)
if err != nil {
return nil, err
}
return &Result{Data: data}, nil
}
// Bad: Returns interface (hides implementation details unnecessarily)
func ProcessData(r io.Reader) (io.Reader, error) {
// ...
}
// Good: Wrap errors with context
func LoadConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("load config %s: %w", path, err)
}
var cfg Config
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("parse config %s: %w", path, err)
}
return &cfg, nil
}
// Define domain-specific errors
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("validation failed on %s: %s", e.Field, e.Message)
}
// Sentinel errors for common cases
var (
ErrNotFound = errors.New("resource not found")
ErrUnauthorized = errors.New("unauthorized")
ErrInvalidInput = errors.New("invalid input")
)
func HandleError(err error) {
// Check for specific error
if errors.Is(err, sql.ErrNoRows) {
log.Println("No records found")
return
}
// Check for error type
var validationErr *ValidationError
if errors.As(err, &validationErr) {
log.Printf("Validation error on field %s: %s",
validationErr.Field, validationErr.Message)
return
}
// Unknown error
log.Printf("Unexpected error: %v", err)
}
// Bad: Ignoring error with blank identifier
result, _ := doSomething()
// Good: Handle or explicitly document why it's safe to ignore
result, err := doSomething()
if err != nil {
return err
}
// Acceptable: When error truly doesn't matter (rare)
_ = writer.Close() // Best-effort cleanup, error logged elsewhere
func WorkerPool(jobs <-chan Job, results chan<- Result, numWorkers int) {
var wg sync.WaitGroup
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range jobs {
results <- process(job)
}
}()
}
…
帮助开发者为代码代理配置性能优化、安全防护与研究优先工作流。
提供数据库迁移、回滚与零停机发布的最佳实践指导,适用于多种 ORM 与 SQL 数据库。
通过双评审智能体对结果进行对抗式校验,提升输出发布前的可靠性
帮助你掌握地道 Rust 模式、所有权与并发实践,编写安全高性能应用。
基于 C++ Core Guidelines 编写、审查并重构更安全现代的 C++ 代码。
为 Claude Code 会话提供系统化校验流程,帮助检查结果正确性与质量。
提供地道 Go 设计模式与最佳实践,帮助编写健壮高效且易维护的应用
提供惯用Go设计模式与最佳实践,帮助构建稳健高效且易维护的应用
提供地道 Kotlin 模式与最佳实践,帮助构建健壮高效且易维护的应用。
帮助开发者掌握地道 Rust 模式、所有权、并发与错误处理实践
讲解 Rust 惯用模式、所有权与并发实践,帮助构建安全高性能应用
帮助你用地道 Go 实践编写测试、基准、模糊测试并提升覆盖率。