Loading...
Loading...
Compare original and translation side by side
| Code Smell | Detection Question | If Yes |
|---|---|---|
| Interface with one impl | Do you have 2+ implementations? | Remove interface |
| Goroutine + WaitGroup | Is work I/O bound or CPU heavy? | Use sequential loop |
| Does wrap add context? | Add operation + ID |
| Channel for return value | Is there actual concurrency? | Use regular return |
| Generic with one type | Used with multiple types? | Use concrete type |
| Context in pure function | Does function do I/O? | Remove context param |
| Tiny extracted function | Called from 2+ places? | Inline it |
| 代码异味 | 检测问题 | 如果是 |
|---|---|---|
| 仅一个实现的接口 | 是否有2个及以上的实现? | 移除接口 |
| Goroutine + WaitGroup | 操作是I/O密集型还是CPU密集型? | 使用顺序循环 |
| 包装是否添加了上下文信息? | 添加操作内容及ID |
| 用于返回值的通道 | 是否存在实际并发场景? | 使用常规返回值 |
| 仅一种类型的泛型 | 是否用于多种类型? | 使用具体类型 |
| 纯函数中的Context | 函数是否执行I/O操作? | 移除Context参数 |
| 提取的小型函数 | 是否在2个及以上位置被调用? | 内联该函数 |
ANTI-PATTERN DETECTED:
- Pattern: [Name from catalog below]
- Location: [File:line]
- Issue: [What is wrong with current approach]
- Impact: [Complexity/performance/maintainability cost]
- Severity: [Low/Medium/High]
- Recommendation: [Simpler Go alternative]检测到反模式:
- 模式:[以下目录中的名称]
- 位置:[文件:行号]
- 问题:当前实现方式的问题所在
- 影响:[复杂度/性能/可维护性成本]
- 严重程度:[低/中/高]
- 建议:[更简洁的Go语言替代方案]references/code-examples.mdreferences/code-examples.md// BAD: Interface before need
type UserRepository interface {
GetUser(id string) (*User, error)
}
type PostgresUserRepository struct{ db *sql.DB }
// Only one implementation exists
// GOOD: Concrete type first
type UserRepository struct{ db *sql.DB }
func (r *UserRepository) GetUser(id string) (*User, error) { ... }
// Add interface when second implementation appears// 不良示例:提前定义接口
type UserRepository interface {
GetUser(id string) (*User, error)
}
type PostgresUserRepository struct{ db *sql.DB }
// 仅存在一个实现
// 良好示例:先使用具体类型
type UserRepository struct{ db *sql.DB }
func (r *UserRepository) GetUser(id string) (*User, error) { ... }
// 当出现第二个实现时再添加接口// BAD: Goroutines for simple iteration
errCh := make(chan error, len(items))
var wg sync.WaitGroup
for _, item := range items {
wg.Add(1)
go func(item Item) { defer wg.Done(); ... }(item)
}
// GOOD: Sequential is clearer
for _, item := range items {
if err := process(item); err != nil {
return fmt.Errorf("process item %s: %w", item.ID, err)
}
}// 不良示例:为简单迭代使用Goroutine
errCh := make(chan error, len(items))
var wg sync.WaitGroup
for _, item := range items {
wg.Add(1)
go func(item Item) { defer wg.Done(); ... }(item)
}
// 良好示例:顺序执行更清晰
for _, item := range items {
if err := process(item); err != nil {
return fmt.Errorf("process item %s: %w", item.ID, err)
}
}// BAD: No context
return nil, fmt.Errorf("error: %w", err)
return nil, fmt.Errorf("failed: %w", err)
// GOOD: Narrative context
return nil, fmt.Errorf("load config from %s: %w", path, err)
return nil, fmt.Errorf("parse config JSON from %s: %w", path, err)// 不良示例:无上下文信息
return nil, fmt.Errorf("error: %w", err)
return nil, fmt.Errorf("failed: %w", err)
// 良好示例:带有上下文的描述
return nil, fmt.Errorf("load config from %s: %w", path, err)
return nil, fmt.Errorf("parse config JSON from %s: %w", path, err)// BAD: Channel for simple return
func GetUserName(id string) <-chan string {
ch := make(chan string, 1)
go func() { ch <- fetchUser(id).Name }()
return ch
}
// GOOD: Direct return
func GetUserName(id string) (string, error) {
user, err := fetchUser(id)
if err != nil { return "", err }
return user.Name, nil
}// 不良示例:使用通道返回简单结果
func GetUserName(id string) <-chan string {
ch := make(chan string, 1)
go func() { ch <- fetchUser(id).Name }()
return ch
}
// 良好示例:直接返回结果
func GetUserName(id string) (string, error) {
user, err := fetchUser(id)
if err != nil { return "", err }
return user.Name, nil
}// BAD: Generic with one type
type Container[T any] struct{ value T }
// Only ever used as Container[string]
// GOOD: Concrete type
type StringContainer struct{ value string }// 不良示例:仅一种类型的泛型
type Container[T any] struct{ value T }
// 仅被用作Container[string]
// 良好示例:使用具体类型
type StringContainer struct{ value string }context.Context// BAD: Context in pure function
func CalculateTotal(ctx context.Context, prices []float64) float64 { ... }
// GOOD: No context needed
func CalculateTotal(prices []float64) float64 { ... }context.Context// 不良示例:纯函数中的Context
func CalculateTotal(ctx context.Context, prices []float64) float64 { ... }
// 良好示例:无需Context
func CalculateTotal(prices []float64) float64 { ... }// BAD: Extracted for metrics
func (opts AuditorOpts) parsePort() (int, error) {
if opts.Port == "" { return 5672, nil }
return strconv.Atoi(opts.Port)
}
// Called exactly once from buildConnectionURL
// GOOD: Inline when called once
func (opts AuditorOpts) buildConnectionURL() (string, error) {
port := 5672
if opts.Port != "" {
var err error
port, err = strconv.Atoi(opts.Port)
if err != nil { return "", fmt.Errorf("parse port %q: %w", opts.Port, err) }
}
return fmt.Sprintf("amqp://%s:%d", opts.Host, port), nil
}// 不良示例:为满足指标提取函数
func (opts AuditorOpts) parsePort() (int, error) {
if opts.Port == "" { return 5672, nil }
return strconv.Atoi(opts.Port)
}
// 仅在buildConnectionURL中被调用一次
// 良好示例:仅被调用一次时内联
func (opts AuditorOpts) buildConnectionURL() (string, error) {
port := 5672
if opts.Port != "" {
var err error
port, err = strconv.Atoi(opts.Port)
if err != nil { return "", fmt.Errorf("parse port %q: %w", opts.Port, err) }
}
return fmt.Sprintf("amqp://%s:%d", opts.Host, port), nil
}| Rationalization | Why It Is Wrong | Required Action |
|---|---|---|
| "This interface might be needed later" | YAGNI; future is unknown | Start concrete, extract when needed |
| "Goroutines make it faster" | Concurrency has overhead; profile first | Prove bottleneck exists before adding goroutines |
| "Context should be everywhere" | Context is for I/O and cancellation only | Remove from pure functions |
| "Generics make it more flexible" | Flexibility without use cases is complexity | Use concrete types until 2+ instantiations |
| "Small functions are always better" | Indirection has cognitive cost | Inline single-use trivial functions |
| 自我辩解 | 错误原因 | 要求操作 |
|---|---|---|
| “这个接口以后可能会用到” | 违反YAGNI原则;未来不可知 | 从具体类型开始,需要时再提取接口 |
| “Goroutine会让代码更快” | 并发存在开销;需先进行性能分析 | 在添加goroutine前证明存在性能瓶颈 |
| “Context应在所有地方使用” | Context仅用于I/O和取消操作 | 从纯函数中移除Context |
| “泛型会让代码更灵活” | 无使用场景的灵活度只会增加复杂度 | 在有2个及以上实例化场景前使用具体类型 |
| “小型函数总是更好” | 间接性会增加认知成本 | 内联仅被调用一次的trivial函数 |
${CLAUDE_SKILL_DIR}/references/code-examples.md${CLAUDE_SKILL_DIR}/references/code-examples.md