golang-patternslisted
Install: claude install-skill omeyang/Thoth
# Go 惯用模式专家
应用 Go 惯用模式编写或审查代码:$ARGUMENTS
---
## 核心原则
### 1. 简洁胜于聪明
Go 代码应该一目了然,不需要思考两次。
```go
// Y: 清晰直接
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
}
```
### 2. 零值可用
设计类型使其零值立即可用,无需初始化。`sync.Mutex` 零值可用,`bytes.Buffer` 零值可用,但 `map` 零值是 nil 会 panic。
### 3. 接收接口,返回具体类型
函数接收 `io.Reader` 等接口参数,返回 `*Result` 等具体类型。不要不必要地返回接口。
---
## 错误处理模式
- **%w 包装**:`fmt.Errorf("load config %s: %w", path, err)` - 保留错误链
- **自定义错误类型**:`ValidationError{Field, Message}` 实现 `error` 接口
- **哨兵错误**:`var ErrNotFound = errors.New("resource not found")`
- **errors.Is / errors.As**:检查特定错误值或错误类型
- **永不忽略错误**:除非明确注释原因
---
## 并发模式
- **Worker Pool**:N 个 goroutine 从 jobs channel 读取,结果写入 results channel
- **Context 取消和超时**:`context.WithTimeout` + `http.NewRequestWithContext`
- **优雅关闭**:`signal.Notify(quit, SIGINT, SIGTERM)` + `server.Shutdown(ctx)`
- **errgroup 协调并发**:`errgroup.WithContext` 并行获取,任一失败则全部取消
- **避免 Goroutine 泄漏**:使用缓冲 channel + select ctx.Done()
---
## 接口设计
- **小而专注**:单方法接口(Reader, Writer, Closer),按需组合
- **在使用方定义**:消费方包定义所需接口,实现方不需知道
- **可选行为的类型断言**:`if f, ok := w.(Flusher); ok { f.Flush() }`
---
## 结构体设计
- **函数选项模式**:`type Option func(*Server)` + `WithTimeout(d)` + `WithLogger(l)`
- **嵌入实现组合**:嵌入 `*Logger` 让 Server 获得 `Log` 方法
---
## 内存和性能
- **预分配切片**:`make([]Result, 0, len(items))`
- **sync.Pool**:频繁分配的对象(如 bytes.Buffer)复用
- **避免循环中的字符串拼接**